Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

SQL Performance - Vienna System Architects Meetup 20131202


Published on

Published in: Technology, Business

SQL Performance - Vienna System Architects Meetup 20131202

  1. 1. Unterschätzte Details der Datenbank-Indizierung (und deren Auswirkung) Vienna System Architects Meetup 2013-12-02 © 2013 by Markus Winand
  2. 2. Was weiß man über Indizierung? Ergebnisse des “3-Minuten Tests” 5 Fragen: Jede prüft das Wissen zu einer bestimmen Indizierungs-Technik ab.
  3. 3. 3-Minute Quiz: Indexing Skills Q1: Good or Bad? (Function use) CREATE  INDEX  tbl_idx  ON  tbl  (date_column); SELECT  text,  date_column    FROM  tbl  WHERE  TO_CHAR(date_column,  'YYYY')  =  '2013';
  4. 4. 3-Minute Quiz: Indexing Skills ...WHERE  TO_CHAR(date_column,  'YYYY')  =  '2013'; Seq  Scan  on  tbl  (rows=365)      Rows  Removed  by  Filter:  49635 Total  runtime:  118.796  ms ...WHERE  date_column  BETWEEN  '2013-­‐01-­‐01'                                                  AND  '2013-­‐12-­‐31' Index  Scan  using  tbl_idx  on  tbl  (rows=365)  Total  runtime:  0.430  ms (Above: simplified PostgreSQL execution plans when selecting 365 rows out of 50000)
  5. 5. 3-Minute Quiz: Indexing Skills Q2: Good or Bad? (Indexed Top-N, no IOS) CREATE  INDEX  tbl_idx  ON  tbl  (a,  date_col); SELECT  id,  a,  date_col    FROM  tbl  WHERE  a  =  ?  ORDER  BY  date_col  DESC  LIMIT  1; Understandable controversy!
  6. 6. 3-Minute Quiz: Indexing Skills It is already the most optimal solution (w/o index-only scan).  Limit  (rows=1)      -­‐>  Index  Scan  Backward  using  tbl_idx  on  tbl    (rows=1)            Index  Cond:  (a  =  123::numeric)    Total  runtime:  0.053  ms As fast as a primary key lookup because it can never return more than one row.
  7. 7. 3-Minute Quiz: Indexing Skills Q3: Good or Bad? (Column order) CREATE INDEX tbl_idx ON tbl (a, b); SELECT id, a, b FROM tbl WHERE a = ? AND b = ?; SELECT id, a, b FROM tbl WHERE b = ?;
  8. 8. 3-Minute Quiz: Indexing Skills As-is only one query can use the index (a,b): ...WHERE a = ? AND b = ?;    Bitmap  Heap  Scan  on  tbl    (rows=6)      -­‐>  Bitmap  Index  Scan  on  tbl_idx  (rows=6)            Index  Cond:  ((a  =  123)  AND  (b  =  1))    Total  runtime:  0.055  ms ...WHERE b = ?;  Seq  Scan  on  tbl  (rows=5142)      Rows  Removed  by  Filter:  44858  Total  runtime:  29.849  ms
  9. 9. 3-Minute Quiz: Indexing Skills Change the index to (b, a) so both can use it: ...WHERE a = ? AND b = ?;    Bitmap  Heap  Scan  on  tbl    (rows=6)      -­‐>  Bitmap  Index  Scan  on  tbl_idx  (rows=6)            Index  Cond:  ((a  =  123)  AND  (b  =  1))    Total  runtime:  0.056  ms ...WHERE b = ?; Bitmap  Heap  Scan  on  tbl  (rows=5142)  -­‐>  Bitmap  Index  Scan  on  tbl_idx    (rows=5142)        Index  Cond:  (b  =  1::numeric) Total  runtime:  6.932  ms
  10. 10. 3-Minute Quiz: Indexing Skills Q4: Good or Bad? CREATE ON SELECT FROM WHERE INDEX tbl_idx tbl (text); id, text tbl text LIKE '%TERM%'; (Indexing LIKE)
  11. 11. 3-Minute Quiz: Indexing Skills B-Tree indexes don’t support prefix wildcards.  Seq  Scan  on  tbl  (rows=0)      Rows  Removed  by  Filter:  50000  Total  runtime:  23.494  ms Using a special purpose index (e.g. in PostgreSQL): CREATE  INDEX  tbl_tgrm  ON  tbl  USING  gin  (text  gin_trgm_ops); Bitmap Heap Scan on tbl (rows=0) Rows Removed by Index Recheck: 2 -> Bitmap Index  Scan on tbl_tgrm (rows=2) Index Cond: ((text)::text ~~ '%TERM%'::text) Total runtime: 0.114  ms
  12. 12. 3-Minute Quiz: Indexing Skills Q5: Good or Bad? (equality vs. ranges) CREATE INDEX tbl_idx ON tbl (date_col, state); SELECT id, date_col, state FROM tbl WHERE date_col >= TO_DATE(‘2008-12-02’) AND state = 'X';
  13. 13. 3-Minute Quiz: Indexing Skills For the curious, the data distribution: SELECT  count(*)    FROM  tbl  WHERE  date_column  >=  TO_DATE(‘2008-­‐12-­‐02’);                -­‐-­‐-­‐>  1826 SELECT  count(*)    FROM  tbl  WHERE  state  =  'X';                                                                  -­‐-­‐-­‐>  10000 SELECT  count(*)    FROM  tbl  WHERE  date_column  >=  TO_DATE(‘2008-­‐12-­‐02’)        AND  state  =  'X';                                                                  -­‐-­‐-­‐>  365
  14. 14. 3-Minute Quiz: Indexing Skills CREATE INDEX tbl_idx ON tbl (date_col, state);  Index  Scan  using  tbl_idx  on  tbl  (rows=365)  Total  runtime:  0.893  ms CREATE INDEX tbl_idx ON tbl (state, date_col); Index  Scan using  tbl_idx  on  tbl  (rows=365)  Total  runtime: 0.530  ms
  15. 15. Indexes: The Neglected All-Rounder Everybody knows indexing is important for performance, yet nobody takes the time to learn and apply is properly.
  16. 16. About Markus Winand Tuning developers for high SQL performance Training & co (one-man show): Author of: SQL Performance Explained Geeky blog: