SlideShare uma empresa Scribd logo
1 de 43
Advanced query optimization
 techniques on large queries
                         Peter Boros
                    Percona Webinar
Agenda
• Showing the title slide
• Going through this agenda
• Prerequisites
• Case study #1
• Case study #2
• Case study #3
• Case study #4

                              www.percona.com
This talk is not about
●
    SQL basics
●
    Reading explain
●
    Indexing basics




                            www.percona.com
Case Study #1
#1: Query
●
    Query runs in the   SELECT t.id, ts.meta1, lt.meta2
                        FROM things t
    10 seconds range    INNER JOIN things_stuff ts
                          ON t.fk_things_stuff_id = ts.id
                        INNER JOIN yet_an_other_table yat
●
    According to          ON t.fk_yat_id = yat.id
                        WHERE t.active = 1
    explain output it   AND t.type != 'guest'
                        AND t.title like '%the%'
                        AND LOWER(t.username) like '%e%'
    can use some        AND t.grants & 1 != 0
                        AND t.attribute1=3;
    indexes
●
    Mostly single-
    column indexes
    were defined
                                           www.percona.com
#1: Query
●
    Rows examined in      SELECT t.id, ts.meta1, lt.meta2
                          FROM things t
    the 100k range        INNER JOIN things_stuff ts
                            ON t.fk_things_stuff_id = ts.id
                          INNER JOIN yet_an_other_table yat
●
    Rows returned is        ON t.fk_yat_id = yat.id
                          WHERE t.active = 1
    single digit          AND t.type != 'guest'
                          AND t.title like '%the%'
                          AND LOWER(t.username) like '%e%'
●
    This means            AND t.grants & 1 != 0
                          AND t.attribute1=3;
    something is
    selective, but most
    likely not indexed

                                             www.percona.com
#1: issue identification
********************** 1. row **********************
           id: 1
  select_type: SIMPLE
        table: t                                     This is the issue, the rest
         type: const                                 of the tables are just some
          key: idx_active                            metadata fetching (type is eq_ref)
      key_len: 4
         rows: 332873
        Extra: Using where
********************** 2. row **********************
           id: 1
  select_type: SIMPLE
        table: ts
         type: eq_ref
          key: PRIMARY
      key_len: 4
         rows: 1
        Extra:
********************** 3. row *****************
         type: eq_ref
         rows: 1

                                                                   www.percona.com
#1: finding the filtering clause
●   In the original query, filtering in the
    WHERE clause are all for table t (things)
●   Find out if any of them are selective alone
    (it's possible that they are not, but some
    combination of them will be selective)
    SELECT COUNT(t.id) FROM things t WHERE t.active=1;
    +----------+
    | COUNT(1) |
    +----------+
    |   168520 |
    +----------+
    1 row in set (10.15 sec)



                                                         www.percona.com
#1: finding the filtering clause
SELECT COUNT(t.id) FROM things t WHERE t.status!='guest';
+----------+
| COUNT(1) |
+----------+
|   284582 |
+----------+
1 row in set (10.13 sec)
SELECT COUNT(t.id) FROM things t WHERE t.title LIKE '%the%';
+----------+
| COUNT(1) |
+----------+
|   173895 |
+----------+
1 row in set (10.12 sec)
SELECT COUNT(t.id) FROM things t WHERE lower(t.username) like '%e%';
+----------+
| COUNT(1) |
+----------+
|   190345 |
+----------+
1 row in set (10.15 sec)

                                                                www.percona.com
#1: finding the filtering clause
SELECT COUNT(t.id) FROM things t WHERE t.grants & 1 != 0;
+----------+
| COUNT(1) |
+----------+
|        4 |
+----------+
1 row in set (10.13 sec)

 ●   This is selective
 ●   In the original table definition the grants
     column has an index on it, but it's not used
     (the index on the not too selective active
     column is used instead)
 ●   Data type of grants in TINYINT
                                                            www.percona.com
#1: reason for slowness
SELECT COUNT(t.id) FROM things t WHERE t.grants & 1 != 0;
+----------+
| COUNT(1) |
+----------+
|        4 |
+----------+
1 row in set (10.13 sec)

 ●   The & is bitwise AND operator
      ●   On the left hand side of comparison it's
          not the column itself, which is indexed,
          but some kind of function of the column
          is compared, which is not indexed.

                                                            www.percona.com
#1: TINYINT column used as
                bitmap
  ●   The grants in this case used as 1 raw byte
      (8 bits), 1 is a mask we compare to
  ●   A common case for this is storing
      privileges   Does some document / user / page
                   has privilege “H”?

                                  1 0 1 0 0 0 0 1
                                         &
Privilege “A”     Privilege “H”
                                  0 0 0 0 0 0 0 1
The result is non-0 when the
appropriate privilege bit is 1.   0 0 0 0 0 0 0 1



                                                    www.percona.com
#1: solution
●   The solution itself is very space efficient,
    but the data is not accessible.
●   If only privilege “H” is checked frequently,
    just create a privilege “H” column, which is
    indexed and store data redundantly
●   If other checks are frequent, use separate
    columns for each privilege
●   Other antipatterns in the query, which are
    not making it slower
                                        www.percona.com
Case Study #2
#2: Query
●
    Query runs in the   SELECT ta.*,
                        tb.attr1,
    10 seconds range    tb.attr2,
                        tb.attr3,
                        tb.attr4,
●
    Rows examined is    tc.attr1
                        FROM table_a ta,
    much higher than    table_b tb,
                        table_c tc
                        WHERE tb.ID = ta.tb_id
    rows returned       AND tc.attr1 = ta.attr1
                        AND tc.attr2 = 1
                        AND ta.attr3 = 'non_selective'
                        AND ta.attr4 = 715988
                        AND ta.attr5 BETWEEN 1 AND 10
                        ORDER BY ta.attr6 ASC




                                           www.percona.com
#2: Explain
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: ta
partitions: NULL
type: ref
possible_keys: idx_attr4,...,idx_attr3,...
key: idx_attr3
key_len: 202
ref: const
rows: 100280
Extra: Using where; Using filesort
*************************** 2. row ***************************
id: 1
table: tb
type: eq_ref
key: PRIMARY
rows: 1
*************************** 3. row ***************************
id: 1
table: tc
type: ref
key: idx_attr1
rows: 2
                                                                 www.percona.com
#2: Show indexes and data
               types
mysql> SHOW INDEX FROM table_a WHERE Key_name = "attr4" OR Key_name = "attr3"G
*************************** 1. row ***************************
Table: table_a
Key_name: attr4
Seq_in_index: 1
Column_name: attr4
Cardinality: 523608
*************************** 2. row ***************************
Table: table_a
Key_name: attr3
Seq_in_index: 1
Column_name: attr4
Cardinality: 21
2 rows in set (0.01 sec)


  `attr3` varchar(200) DEFAULT NULL,
  `attr4` varchar(200) DEFAULT NULL




                                                               www.percona.com
#2: solution
SELECT ta.*,                                SELECT ta.*,
tb.attr1,                                   tb.attr1,
tb.attr2,                                   tb.attr2,
tn.attr3,                                   tn.attr3,
tb.attr4,                                   tb.attr4,
tc.attr1                                    tc.attr1
FROM table_a ta,                            FROM table_a ta,
table_b tb,                                 table_b tb,
table_c tc                                  table_c tc
WHERE tb.ID = ta.tb_id                      WHERE tb.ID = ta.tb_id
AND tc.attr1 = ta.attr1                     AND tc.attr1 = ta.attr1
AND tc.attr2 = 1                            AND tc.attr2 = 1
AND ta.attr3 = 'non_selective'              AND ta.attr3 = 'non_selective'
AND ta.attr4 = 715988                       AND ta.attr4 = '715988'
AND ta.attr5 BETWEEN 1 AND 10               AND ta.attr5 BETWEEN 1 AND 10
ORDER BY a.date_recorded ASC                ORDER BY a.date_recorded ASC

 After this change, the right index is used (changing column type could be better)


                                                                  www.percona.com
#2: conclusion
●   Always quote strings, never quote
    numbers
●   Similar thing can happen when there is a
    data type mismatch between joined tables
    ●   For example an id is in a INT column is
        one table, VARCHAR(x) in the other,
        join won't use indexes on them



                                       www.percona.com
Case Study #3
#3: Query
  SELECT * FROM things WHERE ((thing_id=87459234 AND thing_flag1 = 1)
  OR (thing_other_thing_id=87459234 AND thing_flag2 = 1)) AND
  (thing_id=87459234 OR other_thing_id=87459234) AND (thing_id <>
  3846571 AND other_thing_id <> 3846571) AND (thing_prop1 IS NOT NULL)
  AND (thing_rangedate >= '2012-12-01') OR (thing_rangedate_min >
  '2012-12-03' AND thing_rangedate_max < '2012-12-04')
  AND (NOT EXISTS (SELECT 1 FROM thing_stuffs WHERE fk_things_id =
  things.id AND important_num BETWEEN 1 and 4 AND other_range_value
  between 1 and 3));



If a query is big enough, always start with formatting the query.




                                                         www.percona.com
#3: Query
                          SELECT *
                          FROM things
First issue is clear from WHERE
explain output:           ((thing_id=87459234 AND thing_flag1 = 1)
DEPENDENT SUBQUERY OR (thing_other_thing_id=87459234 AND thing_flag2 = 1))
                          AND (thing_id=87459234 OR other_thing_id=87459234)
                          AND (thing_id <> 3846571 AND other_thing_id <> 3846571)
                          AND (thing_prop1 IS NOT NULL)
                          AND (thing_rangedate >= '2012-12-01')
                          OR (thing_rangedate_min > '2012-12-03'
                          AND thing_rangedate_max < '2012-12-04')

                           AND (NOT EXISTS
                                  (SELECT 1 FROM thing_stuffs
                                   WHERE fk_things_id = things.id
                                   AND important_num BETWEEN 1 and 4
                                   AND other_range_value BETWEEN 1 and 3));




                                                               www.percona.com
#3: Explain
*************************** 1. row ***************************
           id: 1
  select_type: PRIMARY
        table: things
         type: ref
possible_keys: idx_thing_id,idx_other_thing_id,idx_prop1
          key: idx_thing_id
      key_len: 4
         rows: 23917933
        Extra: Using where
*************************** 2. row ***************************
           id: 2
  select_type: DEPENDENT SUBQUERY
        table: thing_stuffs
         type: subquery
possible_keys: PRIMARY,fk_things_id
          key: PRIMARY
      key_len: 4
         rows: 1
        Extra: Using where
2 rows in set (0.01 sec)


                                                                 www.percona.com
#3: Rewrite DEPENDENT
        SUBQUERY
SELECT *
FROM things
WHERE
AND (NOT EXISTS
       (SELECT 1 FROM thing_stuffs
         WHERE fk_things_id = things.id
         AND important_num BETWEEN 1 and 4
         AND other_range_value BETWEEN 1 and 3));




SELECT t.*
FROM things t
LEFT JOIN thing_stuffs ts ON ts.fk_things_id = things.id
WHERE ts.fk_things_id IS NULL
AND ts.important_num BETWEEN 1 AND 4
AND ts.other_range_value BETWEEN 1 AND 3




                                                           www.percona.com
#3: Explain after rewrite
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE                             Composite index on important_num
        table: ts                                 and other_range_value
         type: ref
possible_keys: idx_important_num_other_range
          key: idx_important_num_other_range
      key_len: 4
          ref: const
         rows: 93854
        Extra: Using where
*************************** 2. row ***************************
           id: 1
  select_type: SIMPLE
        table: t
         type: ref
possible_keys: PRIMARY
          key: PRIMARY
      key_len: 4
          ref: ts.fk_things_id
         rows: 5
        Extra: Using where
2 rows in set (0.01 sec)

                                                              www.percona.com
#3: Examining further
Still more rows examined than returned.
possible_keys:   idx_important_num_other_range
          key:   idx_important_num_other_range
      key_len:   4
         rows:   93854

The index is a composite index, however only important_num is used
mysql> SELECT COUNT(1) FROM thing_stuffs WHERE important_num BETWEEN 1 AND 4;
+----------+
| count(1) |
+----------+
|    87520 |
+----------+
1 row in set (0.15 sec)
mysql> SELECT COUNT(1) FROM thing_stuffs WHERE other_range_value BETWEEN 1 AND 3;
+----------+
| count(1) |
+----------+
|   134526 |
+----------+
1 row in set (0.17 sec)

                                                                  www.percona.com
#3: Examining further
mysql> SELECT COUNT(1) FROM thing_stuff WHERE important_num BETWEEN 1 AND 4
AND other_range_value BETWEEN 1 AND 3;
+----------+
| count(1) |
+----------+
|      125 |
+----------+
1 row in set (0.15 sec)
  ●   Together they are selective
  ●   Both of them are range conditions, so they
      can't be used together in a composite
      index
  ●   Unless we rewrite

                                                                www.percona.com
#3: Second rewrite
SELECT COUNT(1) from thing_stuff WHERE important_num IN (1,2,3,4) AND
other_range_value IN (1,2,3);
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: ts
         type: ref
          key: idx_important_num_other_range
      key_len: 8
          ref: const
         rows: 125
        Extra: Using where
*************************** 2. row ***************************
           id: 1
  select_type: SIMPLE
        table: t
         type: ref
          key: PRIMARY
      key_len: 4
          ref: ts.fk_things_id
         rows: 5
        Extra: Using where
2 rows in set (0.01 sec)

                                                                   www.percona.com
#3: Using it in the original
                   query
The query is still slow.     SELECT t.*
                             FROM things t
                             LEFT JOIN thing_stuffs ts ON ts.fk_things_id = t.id
A lot more rows examined     WHERE ((t.thing_id=87459234 AND t.thing_flag1 = 1)
Than returned.               OR (t.other_thing_id=87459234 AND t.thing_flag2 = 1))
                             AND (t.thing_id=87459234 OR t.other_thing_id=87459234)
                             AND (t.thing_id <> 3846571
Checking explain the         AND t.other_thing_id <> 3846571)
relevant part is that the    AND (t.thing_prop1 IS NOT NULL)
query uses an index merge.   AND (t.thing_rangedate >= '2012-12-01')
                             OR (t.thing_rangedate_min > '2012-12-03'
                             AND t.thing_rangedate_max < '2012-12-04')
                             AND ts.important_num IN (1,2,3,4)
                             AND ts.other_range_value IN (1,2,3)
                             AND ts.fk_things_id IS NULL;



    Extra: Using union(idx_thing_id,idx_other_thing_id); Using where



                                                                www.percona.com
#3: Relevant part
SELECT * FROM things
WHERE (thing_id=87459234 OR other_thing_id=87459234)
AND thing_id <> 3846571 AND other_thing_id <> 3846571;
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: things
         type: index_merge
possible_keys: idx_thing_id,idx_other_thing_id
          key: idx_thing_id,idx_other_thing_id
      key_len: 4,4
          ref: NULL
         rows: 59834
        Extra: Using union(idx_thing_id,idx_other_thing_id); Using where
1 row in set (0.00 sec)




                                                                 www.percona.com
#3: Rewritten query
 ●   Index merge is an expensive                  SELECT *
                                                  FROM things
     operation                                    WHERE thing_id=87459234
                                                  AND other_thing_id<>3846571
      ●   Especially if indexes are large         UNION
                                                  SELECT *
                                                  FROM things
 ●   UNION always create an on-disk               WHERE other_thing_id=87459234
     temp table                                   AND thing_id<>3846571;

 ●   Just turning off index merge
     could be enough for a significant
     performance advantage
mysql> select @@optimizer_switchG
*************************** 1. row ***************************
@@optimizer_switch:
index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_interse
ction=on,engine_condition_pushdown=on
1 row in set (0.00 sec)


                                                                www.percona.com
#3: Putting it together
SELECT t.* FROM things t
LEFT JOIN things_stuff ts
ON ts.fk_things_id = t.id
WHERE t.thing_id=87459234
AND t.other_thing_id<>3846571
AND t.thing_flag1=1
AND t.thing_prop IS NOT NULL                  SELECT t.* FROM things t
AND (t.thing_rangedate_min >= '2012-12-01')   LEFT JOIN t.things_stuff ts
AND ((t.thing_rangedate_min <= '2012-12-03'   ON ts.fk_things_id = t.id
AND t.thing_rangedate_max > '2012-12-03')     WHERE t.other_thing_id=87459234
OR (t.thing_rangedate_min < '2012-12-04'      AND t.thing_id<>3846571
AND t.thing_rangedate_max >= '2012-12-04')    AND t.thing_flag2=1
OR (t.thing_rangedate_min > '2012-12-03'      AND t.thing_prop1 IS NOT NULL
AND t.thing_rangerate_max < '2012-12-04'))    AND (t.thing_rangedate_min >= '2012-12-01')
AND ts.fk_things_id IS NULL                   AND ((t.thing_rangedate_min <= '2012-12-03'
AND ts.important_num IN (1,2,3,4)             AND t.thing_rangedate_max > '2012-12-03')
AND ts.other_range_value IN (1,2,3)           OR (t.thing_rangedate_min < '2012-12-04'
UNION                                         AND t.thing_rangedate_max >= '2012-12-04')
                                              OR (t.thing_rangedate_min > '2012-12-03'
                                              AND t.thing_rangedate_max < '2012-12-04'))
                                              AND ts.fk_things_id IS NULL
                                              AND ts.important_num IN (1,2,3,4)
                                              AND ts.other_range_value IN (1,2,3);

                                                                     www.percona.com
Case Study #4
#4: Summary
●   Very large, 20 table join
●   Explain looks ok
●   Query runs for almost a hour
●   Handler status variables are way off




                                     www.percona.com
#4: Query
SELECT tmain.id, tmain.date,
CONCAT_WS("_", COALESCE(m1.col1, 'n/a'), COALESCE(m2.col2, 'n/a')
/* a lot more columns selected */)
FROM main_table as tmain ah
LEFT JOIN
(metadata_table1 m1 JOIN metadata_table2 m2 ON m1.attr1 = m2.attr1 AND m1.const =   'some text')
ON tmain.id = m1.tmain_id AND tmain.important_flag=1
AND ((m1.attr11='a') OR (m2.attr12 IS NOT NULL) AND 3>=m1.attr13 AND 5<m2.attr14)
OR m1.attr15 IS NOT NULL AND m2.attr16 BETWEEN 1 AND 10
LEFT JOIN
(metadata_table3 m3 JOIN metadata_table4 m4 ON m3.attr1 = m4.attr1 AND m1.const =   'some text')
ON tmain.id = m4.tmain_id AND tmain.important_flag=1
AND ((m3.attr11='a') OR (m4.attr12 IS NOT NULL) AND 3>=m3.attr13 AND 5<m4.attr14)
OR m3.attr15 IS NOT NULL AND m4.attr16 BETWEEN 11 AND 20
LEFT JOIN
(metadata_table5 m5 JOIN metadata_table2 m6 ON m5.attr1 = m6.attr1 AND m1.const =   'some text')
ON tmain.id = m5.tmain_id AND tmain.important_flag=1
AND ((m5.attr11='a') OR (m6.attr12 IS NOT NULL) AND 3>=m5.attr13 AND 5<m6.attr14)
OR m1.attr15 IS NOT NULL AND m2.attr16 BETWEEN 21 AND 30
LEFT JOIN
(metadata_table1 m7 JOIN metadata_table2 m8 ON m7.attr1 = m8.attr1 AND m7.const =   'some text')
ON tmain.id = m7.tmain_id AND tmain.important_flag=1
AND ((m7.attr11='a') OR (m8.attr12 IS NOT NULL) AND 3>=m7.attr13 AND 5<m8.attr14)
OR m7.attr15 IS NOT NULL AND m8.attr16 BETWEEN 31 AND 40
/* 6 more joins exactly like the previous ones... */
WHERE tmain.important_flag = 1;

                                                                          www.percona.com
#4: Explain (only relevant part)
+----+-------------+----------+--------+------+-------------+
| id | select_type | table    | type   | rows | Extra       |
+----+-------------+----------+--------+------+-------------+
| 1 | SIMPLE       | tmain    | ref    | 1786 |             |
| 1 | SIMPLE       | m1       | ref    |    4 |             |
| 1 | SIMPLE       | m2       | eq_ref |    1 | Using index |
| 1 | SIMPLE       | m3       | ref    |    4 |             |
| 1 | SIMPLE       | m4       | eq_ref |    1 | Using index |
|....|.............|..........|........|......|.............|
| 1 | SIMPLE       | m19      | ref    |    4 |             |
| 1 | SIMPLE       | m20      | eq_ref |    1 | Using index |
+----+-------------+----------+--------+------+-------------+




                                                                www.percona.com
#4: Handler operations
                                  mysql> show status like 'Handler%';
                                  +----------------------------+-----------+
Run FLUSH STATUS before the query | Variable_name              | Value      |
                                  +----------------------------+-----------+
to reset the counters.            | Handler_commit             |          1 |
                                  | Handler_delete             |          0 |
                                  | Handler_discover           |          0 |
FLUSH STATUS;                     | Handler_prepare            |          0 |
QUERY;                            | Handler_read_first         |          0 |
                                  | Handler_read_key           |      61341 |
SHOW STATUS LIKE 'Handler%';      | Handler_read_last          |          0 |
                                  | Handler_read_next          | 198008370 |
                                  | Handler_read_prev          |          0 |
                                  | Handler_read_rnd           |          0 |
                                  | Handler_read_rnd_next      |          0 |
                                  | Handler_rollback           |          0 |
                                  | Handler_savepoint          |          0 |
                                  | Handler_savepoint_rollback |          0 |
                                  | Handler_update             |          0 |
                                  | Handler_write              |          0 |
                                  +----------------------------+-----------+



                                                            www.percona.com
#4: Problematic part
LEFT JOIN
(metadata_table1 m7 JOIN metadata_table2 m8 ON m7.attr1 = m8.attr1
AND m7.const = 'some text')
ON tmain.id = m7.tmain_id AND tmain.important_flag=1;

SELECT AVG(LENGTH(m1.somefield))
FROM metadata_table1 m1
JOIN metadata_table2 m2
ON m1.attr1 = m2.attr1
AND m1.const='some text'
+----+-------------+----------+--------+-------+-------------+
| id | select_type | table    | type   | rows | Extra        |
+----+-------------+----------+--------+-------+-------------+
| 1 | SIMPLE       | m1       | ref    | 19764 |             |
| 1 | SIMPLE       | m2       | eq_ref |   102 | Using index |
+----+-------------+----------+--------+-------+-------------+
MySQL executes the join like this. One “problematic part takes roughly 3 minutes, so
It adds up.


                                                                 www.percona.com
#4: Rewrite
SELECT tmain.id
FROM main_table tmain
LEFT JOIN metadata_table1 m1 ON tmain.id=m1.tmain_id
LEFT JOIN metadata_table2 m2 ON m1.attr1 = m2.attr1
AND m1.const = 'some text'
WHERE tmain.important_flag = 1;

  ●   In order to leave out () LEFT JOIN has to be used to
      find non-matching elements.
  ●   Runtime for query is 0.2 sec instead of 3 minutes.
       +----+-------------+----------+--------+------+-------------+
       | id | select_type | table    | type   | rows | Extra       |
       +----+-------------+----------+--------+------+-------------+
       | 1 | SIMPLE       | tmain    | ref    | 1786 |             |
       | 1 | SIMPLE       | m1       | ref    |    4 |             |
       | 1 | SIMPLE       | m2       | eq_ref |    1 | Using index |
       +----+-------------+----------+--------+------+-------------+


                                                                www.percona.com
#4: Similarly large queries
●   After applying the tuning to the original query, I
    expected it t execute in a few seconds.
●   It executed in 4 minutes instead.
●   Used Handler operations looked good.
●   Took a look at explain, and explain took 4 minutes
    also.
    ●   This means the optimizer spends time in
        constructing the query plan.
    ●   Solution: STRAIGHT_JOIN and/or
        optimizer_search_depth

                                                www.percona.com
Annual Percona Live
MySQL Conference and Expo




                       Visit:
 http://www.percona.com/live/mysql-conference-2013/
                                         www.percona.com
Q&A
Thank you for attention.

Mais conteúdo relacionado

Destaque

TOPPS Cairo May 17th 2016 v1.2
TOPPS Cairo May 17th 2016 v1.2TOPPS Cairo May 17th 2016 v1.2
TOPPS Cairo May 17th 2016 v1.2TAQAMISR
 
Platinum Tools 12507C Data Sheet
Platinum Tools 12507C Data SheetPlatinum Tools 12507C Data Sheet
Platinum Tools 12507C Data SheetJMAC Supply
 
давление в жидкостях и газах 2
давление в жидкостях и газах 2давление в жидкостях и газах 2
давление в жидкостях и газах 2fangizf68123
 
Ata 44 da ceext 1ª câmara
Ata 44 da  ceext 1ª câmaraAta 44 da  ceext 1ª câmara
Ata 44 da ceext 1ª câmaraG. Gomes
 
TAQAMISR May 17th 2016
TAQAMISR May 17th 2016TAQAMISR May 17th 2016
TAQAMISR May 17th 2016TAQAMISR
 
Ata 42 ceext transposição de servidores
Ata 42  ceext   transposição de servidoresAta 42  ceext   transposição de servidores
Ata 42 ceext transposição de servidoresG. Gomes
 
Tabela de Taxas Veiculares-2017
Tabela de Taxas Veiculares-2017Tabela de Taxas Veiculares-2017
Tabela de Taxas Veiculares-2017G. Gomes
 
The Power of MySQL Explain
The Power of MySQL ExplainThe Power of MySQL Explain
The Power of MySQL ExplainMYXPLAIN
 
Hasil keputusan rapat rt 03
Hasil keputusan rapat rt 03Hasil keputusan rapat rt 03
Hasil keputusan rapat rt 03Ikhsan Arvis
 
Apa referencing guide 6th ed 2014 update
Apa referencing guide 6th ed 2014 updateApa referencing guide 6th ed 2014 update
Apa referencing guide 6th ed 2014 updateLiza Ainurahmah II
 
Optimizing Queries with Explain
Optimizing Queries with ExplainOptimizing Queries with Explain
Optimizing Queries with ExplainMYXPLAIN
 
QUALITY MANAGEMENT PRACTICES USED BY TELECOM ORGANIZATIONS,quality in telecom...
QUALITY MANAGEMENT PRACTICES USED BY TELECOM ORGANIZATIONS,quality in telecom...QUALITY MANAGEMENT PRACTICES USED BY TELECOM ORGANIZATIONS,quality in telecom...
QUALITY MANAGEMENT PRACTICES USED BY TELECOM ORGANIZATIONS,quality in telecom...Micky Lyf
 
Rechtsupdate 2016 - Community Camp Berlin 2016 - #ccb16
Rechtsupdate 2016 - Community Camp Berlin 2016 -  #ccb16Rechtsupdate 2016 - Community Camp Berlin 2016 -  #ccb16
Rechtsupdate 2016 - Community Camp Berlin 2016 - #ccb16Thomas Schwenke
 

Destaque (15)

TOPPS Cairo May 17th 2016 v1.2
TOPPS Cairo May 17th 2016 v1.2TOPPS Cairo May 17th 2016 v1.2
TOPPS Cairo May 17th 2016 v1.2
 
Techos verdes
Techos verdesTechos verdes
Techos verdes
 
Platinum Tools 12507C Data Sheet
Platinum Tools 12507C Data SheetPlatinum Tools 12507C Data Sheet
Platinum Tools 12507C Data Sheet
 
давление в жидкостях и газах 2
давление в жидкостях и газах 2давление в жидкостях и газах 2
давление в жидкостях и газах 2
 
Ata 44 da ceext 1ª câmara
Ata 44 da  ceext 1ª câmaraAta 44 da  ceext 1ª câmara
Ata 44 da ceext 1ª câmara
 
TAQAMISR May 17th 2016
TAQAMISR May 17th 2016TAQAMISR May 17th 2016
TAQAMISR May 17th 2016
 
Ata 42 ceext transposição de servidores
Ata 42  ceext   transposição de servidoresAta 42  ceext   transposição de servidores
Ata 42 ceext transposição de servidores
 
Tabela de Taxas Veiculares-2017
Tabela de Taxas Veiculares-2017Tabela de Taxas Veiculares-2017
Tabela de Taxas Veiculares-2017
 
The Power of MySQL Explain
The Power of MySQL ExplainThe Power of MySQL Explain
The Power of MySQL Explain
 
Hasil keputusan rapat rt 03
Hasil keputusan rapat rt 03Hasil keputusan rapat rt 03
Hasil keputusan rapat rt 03
 
Apa referencing guide 6th ed 2014 update
Apa referencing guide 6th ed 2014 updateApa referencing guide 6th ed 2014 update
Apa referencing guide 6th ed 2014 update
 
Optimizing Queries with Explain
Optimizing Queries with ExplainOptimizing Queries with Explain
Optimizing Queries with Explain
 
QUALITY MANAGEMENT PRACTICES USED BY TELECOM ORGANIZATIONS,quality in telecom...
QUALITY MANAGEMENT PRACTICES USED BY TELECOM ORGANIZATIONS,quality in telecom...QUALITY MANAGEMENT PRACTICES USED BY TELECOM ORGANIZATIONS,quality in telecom...
QUALITY MANAGEMENT PRACTICES USED BY TELECOM ORGANIZATIONS,quality in telecom...
 
Binder1
Binder1Binder1
Binder1
 
Rechtsupdate 2016 - Community Camp Berlin 2016 - #ccb16
Rechtsupdate 2016 - Community Camp Berlin 2016 -  #ccb16Rechtsupdate 2016 - Community Camp Berlin 2016 -  #ccb16
Rechtsupdate 2016 - Community Camp Berlin 2016 - #ccb16
 

Semelhante a Advanced Query Optimization Techniques

How to tune a query - ODTUG 2012
How to tune a query - ODTUG 2012How to tune a query - ODTUG 2012
How to tune a query - ODTUG 2012Connor McDonald
 
MySQL Query tuning 101
MySQL Query tuning 101MySQL Query tuning 101
MySQL Query tuning 101Sveta Smirnova
 
MySQL Query Optimisation 101
MySQL Query Optimisation 101MySQL Query Optimisation 101
MySQL Query Optimisation 101Federico Razzoli
 
Python Programming for basic beginners.pptx
Python Programming for basic beginners.pptxPython Programming for basic beginners.pptx
Python Programming for basic beginners.pptxmohitesoham12
 
Data structures and algorithms
Data structures and algorithmsData structures and algorithms
Data structures and algorithmsJulie Iskander
 
Python course in_mumbai
Python course in_mumbaiPython course in_mumbai
Python course in_mumbaivibrantuser
 
Python course in_mumbai
Python course in_mumbaiPython course in_mumbai
Python course in_mumbaivibrantuser
 
Discover the power of Recursive SQL and query transformation with Informix da...
Discover the power of Recursive SQL and query transformation with Informix da...Discover the power of Recursive SQL and query transformation with Informix da...
Discover the power of Recursive SQL and query transformation with Informix da...Ajay Gupte
 
MariaDB's join optimizer: how it works and current fixes
MariaDB's join optimizer: how it works and current fixesMariaDB's join optimizer: how it works and current fixes
MariaDB's join optimizer: how it works and current fixesSergey Petrunya
 
Advance sql session - strings
Advance sql  session - stringsAdvance sql  session - strings
Advance sql session - stringsEyal Trabelsi
 
Improve Your Edge on Machine Learning - Day 1.pptx
Improve Your Edge on Machine Learning - Day 1.pptxImprove Your Edge on Machine Learning - Day 1.pptx
Improve Your Edge on Machine Learning - Day 1.pptxCatherineVania1
 
SQL Joins and Query Optimization
SQL Joins and Query OptimizationSQL Joins and Query Optimization
SQL Joins and Query OptimizationBrian Gallagher
 
Lecture-15-Tuples-and-Dictionaries-Oct23-2018.pptx
Lecture-15-Tuples-and-Dictionaries-Oct23-2018.pptxLecture-15-Tuples-and-Dictionaries-Oct23-2018.pptx
Lecture-15-Tuples-and-Dictionaries-Oct23-2018.pptxlokeshgoud13
 

Semelhante a Advanced Query Optimization Techniques (20)

How to tune a query - ODTUG 2012
How to tune a query - ODTUG 2012How to tune a query - ODTUG 2012
How to tune a query - ODTUG 2012
 
MySQL Query tuning 101
MySQL Query tuning 101MySQL Query tuning 101
MySQL Query tuning 101
 
Python
PythonPython
Python
 
MySQL Query Optimisation 101
MySQL Query Optimisation 101MySQL Query Optimisation 101
MySQL Query Optimisation 101
 
Python Programming for basic beginners.pptx
Python Programming for basic beginners.pptxPython Programming for basic beginners.pptx
Python Programming for basic beginners.pptx
 
Data structures and algorithms
Data structures and algorithmsData structures and algorithms
Data structures and algorithms
 
Python course in_mumbai
Python course in_mumbaiPython course in_mumbai
Python course in_mumbai
 
Python course in_mumbai
Python course in_mumbaiPython course in_mumbai
Python course in_mumbai
 
Data Structures 6
Data Structures 6Data Structures 6
Data Structures 6
 
Discover the power of Recursive SQL and query transformation with Informix da...
Discover the power of Recursive SQL and query transformation with Informix da...Discover the power of Recursive SQL and query transformation with Informix da...
Discover the power of Recursive SQL and query transformation with Informix da...
 
MariaDB's join optimizer: how it works and current fixes
MariaDB's join optimizer: how it works and current fixesMariaDB's join optimizer: how it works and current fixes
MariaDB's join optimizer: how it works and current fixes
 
Ch02
Ch02Ch02
Ch02
 
Advance sql session - strings
Advance sql  session - stringsAdvance sql  session - strings
Advance sql session - strings
 
Improve Your Edge on Machine Learning - Day 1.pptx
Improve Your Edge on Machine Learning - Day 1.pptxImprove Your Edge on Machine Learning - Day 1.pptx
Improve Your Edge on Machine Learning - Day 1.pptx
 
Python study material
Python study materialPython study material
Python study material
 
SQL Joins and Query Optimization
SQL Joins and Query OptimizationSQL Joins and Query Optimization
SQL Joins and Query Optimization
 
Data type in c
Data type in cData type in c
Data type in c
 
Dbms &amp; oracle
Dbms &amp; oracleDbms &amp; oracle
Dbms &amp; oracle
 
Lecture-15-Tuples-and-Dictionaries-Oct23-2018.pptx
Lecture-15-Tuples-and-Dictionaries-Oct23-2018.pptxLecture-15-Tuples-and-Dictionaries-Oct23-2018.pptx
Lecture-15-Tuples-and-Dictionaries-Oct23-2018.pptx
 
Python course
Python coursePython course
Python course
 

Mais de MYXPLAIN

Query Optimization with MySQL 5.6: Old and New Tricks
Query Optimization with MySQL 5.6: Old and New TricksQuery Optimization with MySQL 5.6: Old and New Tricks
Query Optimization with MySQL 5.6: Old and New TricksMYXPLAIN
 
Need for Speed: MySQL Indexing
Need for Speed: MySQL IndexingNeed for Speed: MySQL Indexing
Need for Speed: MySQL IndexingMYXPLAIN
 
Advanced Query Optimizer Tuning and Analysis
Advanced Query Optimizer Tuning and AnalysisAdvanced Query Optimizer Tuning and Analysis
Advanced Query Optimizer Tuning and AnalysisMYXPLAIN
 
MySQL Index Cookbook
MySQL Index CookbookMySQL Index Cookbook
MySQL Index CookbookMYXPLAIN
 
Advanced MySQL Query and Schema Tuning
Advanced MySQL Query and Schema TuningAdvanced MySQL Query and Schema Tuning
Advanced MySQL Query and Schema TuningMYXPLAIN
 
Are You Getting the Best of your MySQL Indexes
Are You Getting the Best of your MySQL IndexesAre You Getting the Best of your MySQL Indexes
Are You Getting the Best of your MySQL IndexesMYXPLAIN
 
How to Design Indexes, Really
How to Design Indexes, ReallyHow to Design Indexes, Really
How to Design Indexes, ReallyMYXPLAIN
 
MySQL 5.6 Performance
MySQL 5.6 PerformanceMySQL 5.6 Performance
MySQL 5.6 PerformanceMYXPLAIN
 
MySQL Indexing - Best practices for MySQL 5.6
MySQL Indexing - Best practices for MySQL 5.6MySQL Indexing - Best practices for MySQL 5.6
MySQL Indexing - Best practices for MySQL 5.6MYXPLAIN
 
56 Query Optimization
56 Query Optimization56 Query Optimization
56 Query OptimizationMYXPLAIN
 
Tools and Techniques for Index Design
Tools and Techniques for Index DesignTools and Techniques for Index Design
Tools and Techniques for Index DesignMYXPLAIN
 
Powerful Explain in MySQL 5.6
Powerful Explain in MySQL 5.6Powerful Explain in MySQL 5.6
Powerful Explain in MySQL 5.6MYXPLAIN
 
Improving Performance with Better Indexes
Improving Performance with Better IndexesImproving Performance with Better Indexes
Improving Performance with Better IndexesMYXPLAIN
 
Explaining the MySQL Explain
Explaining the MySQL ExplainExplaining the MySQL Explain
Explaining the MySQL ExplainMYXPLAIN
 
Covering indexes
Covering indexesCovering indexes
Covering indexesMYXPLAIN
 
MySQL Optimizer Overview
MySQL Optimizer OverviewMySQL Optimizer Overview
MySQL Optimizer OverviewMYXPLAIN
 

Mais de MYXPLAIN (16)

Query Optimization with MySQL 5.6: Old and New Tricks
Query Optimization with MySQL 5.6: Old and New TricksQuery Optimization with MySQL 5.6: Old and New Tricks
Query Optimization with MySQL 5.6: Old and New Tricks
 
Need for Speed: MySQL Indexing
Need for Speed: MySQL IndexingNeed for Speed: MySQL Indexing
Need for Speed: MySQL Indexing
 
Advanced Query Optimizer Tuning and Analysis
Advanced Query Optimizer Tuning and AnalysisAdvanced Query Optimizer Tuning and Analysis
Advanced Query Optimizer Tuning and Analysis
 
MySQL Index Cookbook
MySQL Index CookbookMySQL Index Cookbook
MySQL Index Cookbook
 
Advanced MySQL Query and Schema Tuning
Advanced MySQL Query and Schema TuningAdvanced MySQL Query and Schema Tuning
Advanced MySQL Query and Schema Tuning
 
Are You Getting the Best of your MySQL Indexes
Are You Getting the Best of your MySQL IndexesAre You Getting the Best of your MySQL Indexes
Are You Getting the Best of your MySQL Indexes
 
How to Design Indexes, Really
How to Design Indexes, ReallyHow to Design Indexes, Really
How to Design Indexes, Really
 
MySQL 5.6 Performance
MySQL 5.6 PerformanceMySQL 5.6 Performance
MySQL 5.6 Performance
 
MySQL Indexing - Best practices for MySQL 5.6
MySQL Indexing - Best practices for MySQL 5.6MySQL Indexing - Best practices for MySQL 5.6
MySQL Indexing - Best practices for MySQL 5.6
 
56 Query Optimization
56 Query Optimization56 Query Optimization
56 Query Optimization
 
Tools and Techniques for Index Design
Tools and Techniques for Index DesignTools and Techniques for Index Design
Tools and Techniques for Index Design
 
Powerful Explain in MySQL 5.6
Powerful Explain in MySQL 5.6Powerful Explain in MySQL 5.6
Powerful Explain in MySQL 5.6
 
Improving Performance with Better Indexes
Improving Performance with Better IndexesImproving Performance with Better Indexes
Improving Performance with Better Indexes
 
Explaining the MySQL Explain
Explaining the MySQL ExplainExplaining the MySQL Explain
Explaining the MySQL Explain
 
Covering indexes
Covering indexesCovering indexes
Covering indexes
 
MySQL Optimizer Overview
MySQL Optimizer OverviewMySQL Optimizer Overview
MySQL Optimizer Overview
 

Último

Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clashcharlottematthew16
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DaySri Ambati
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 

Último (20)

Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clash
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 

Advanced Query Optimization Techniques

  • 1. Advanced query optimization techniques on large queries Peter Boros Percona Webinar
  • 2. Agenda • Showing the title slide • Going through this agenda • Prerequisites • Case study #1 • Case study #2 • Case study #3 • Case study #4 www.percona.com
  • 3. This talk is not about ● SQL basics ● Reading explain ● Indexing basics www.percona.com
  • 5. #1: Query ● Query runs in the SELECT t.id, ts.meta1, lt.meta2 FROM things t 10 seconds range INNER JOIN things_stuff ts ON t.fk_things_stuff_id = ts.id INNER JOIN yet_an_other_table yat ● According to ON t.fk_yat_id = yat.id WHERE t.active = 1 explain output it AND t.type != 'guest' AND t.title like '%the%' AND LOWER(t.username) like '%e%' can use some AND t.grants & 1 != 0 AND t.attribute1=3; indexes ● Mostly single- column indexes were defined www.percona.com
  • 6. #1: Query ● Rows examined in SELECT t.id, ts.meta1, lt.meta2 FROM things t the 100k range INNER JOIN things_stuff ts ON t.fk_things_stuff_id = ts.id INNER JOIN yet_an_other_table yat ● Rows returned is ON t.fk_yat_id = yat.id WHERE t.active = 1 single digit AND t.type != 'guest' AND t.title like '%the%' AND LOWER(t.username) like '%e%' ● This means AND t.grants & 1 != 0 AND t.attribute1=3; something is selective, but most likely not indexed www.percona.com
  • 7. #1: issue identification ********************** 1. row ********************** id: 1 select_type: SIMPLE table: t This is the issue, the rest type: const of the tables are just some key: idx_active metadata fetching (type is eq_ref) key_len: 4 rows: 332873 Extra: Using where ********************** 2. row ********************** id: 1 select_type: SIMPLE table: ts type: eq_ref key: PRIMARY key_len: 4 rows: 1 Extra: ********************** 3. row ***************** type: eq_ref rows: 1 www.percona.com
  • 8. #1: finding the filtering clause ● In the original query, filtering in the WHERE clause are all for table t (things) ● Find out if any of them are selective alone (it's possible that they are not, but some combination of them will be selective) SELECT COUNT(t.id) FROM things t WHERE t.active=1; +----------+ | COUNT(1) | +----------+ | 168520 | +----------+ 1 row in set (10.15 sec) www.percona.com
  • 9. #1: finding the filtering clause SELECT COUNT(t.id) FROM things t WHERE t.status!='guest'; +----------+ | COUNT(1) | +----------+ | 284582 | +----------+ 1 row in set (10.13 sec) SELECT COUNT(t.id) FROM things t WHERE t.title LIKE '%the%'; +----------+ | COUNT(1) | +----------+ | 173895 | +----------+ 1 row in set (10.12 sec) SELECT COUNT(t.id) FROM things t WHERE lower(t.username) like '%e%'; +----------+ | COUNT(1) | +----------+ | 190345 | +----------+ 1 row in set (10.15 sec) www.percona.com
  • 10. #1: finding the filtering clause SELECT COUNT(t.id) FROM things t WHERE t.grants & 1 != 0; +----------+ | COUNT(1) | +----------+ | 4 | +----------+ 1 row in set (10.13 sec) ● This is selective ● In the original table definition the grants column has an index on it, but it's not used (the index on the not too selective active column is used instead) ● Data type of grants in TINYINT www.percona.com
  • 11. #1: reason for slowness SELECT COUNT(t.id) FROM things t WHERE t.grants & 1 != 0; +----------+ | COUNT(1) | +----------+ | 4 | +----------+ 1 row in set (10.13 sec) ● The & is bitwise AND operator ● On the left hand side of comparison it's not the column itself, which is indexed, but some kind of function of the column is compared, which is not indexed. www.percona.com
  • 12. #1: TINYINT column used as bitmap ● The grants in this case used as 1 raw byte (8 bits), 1 is a mask we compare to ● A common case for this is storing privileges Does some document / user / page has privilege “H”? 1 0 1 0 0 0 0 1 & Privilege “A” Privilege “H” 0 0 0 0 0 0 0 1 The result is non-0 when the appropriate privilege bit is 1. 0 0 0 0 0 0 0 1 www.percona.com
  • 13. #1: solution ● The solution itself is very space efficient, but the data is not accessible. ● If only privilege “H” is checked frequently, just create a privilege “H” column, which is indexed and store data redundantly ● If other checks are frequent, use separate columns for each privilege ● Other antipatterns in the query, which are not making it slower www.percona.com
  • 15. #2: Query ● Query runs in the SELECT ta.*, tb.attr1, 10 seconds range tb.attr2, tb.attr3, tb.attr4, ● Rows examined is tc.attr1 FROM table_a ta, much higher than table_b tb, table_c tc WHERE tb.ID = ta.tb_id rows returned AND tc.attr1 = ta.attr1 AND tc.attr2 = 1 AND ta.attr3 = 'non_selective' AND ta.attr4 = 715988 AND ta.attr5 BETWEEN 1 AND 10 ORDER BY ta.attr6 ASC www.percona.com
  • 16. #2: Explain *************************** 1. row *************************** id: 1 select_type: SIMPLE table: ta partitions: NULL type: ref possible_keys: idx_attr4,...,idx_attr3,... key: idx_attr3 key_len: 202 ref: const rows: 100280 Extra: Using where; Using filesort *************************** 2. row *************************** id: 1 table: tb type: eq_ref key: PRIMARY rows: 1 *************************** 3. row *************************** id: 1 table: tc type: ref key: idx_attr1 rows: 2 www.percona.com
  • 17. #2: Show indexes and data types mysql> SHOW INDEX FROM table_a WHERE Key_name = "attr4" OR Key_name = "attr3"G *************************** 1. row *************************** Table: table_a Key_name: attr4 Seq_in_index: 1 Column_name: attr4 Cardinality: 523608 *************************** 2. row *************************** Table: table_a Key_name: attr3 Seq_in_index: 1 Column_name: attr4 Cardinality: 21 2 rows in set (0.01 sec) `attr3` varchar(200) DEFAULT NULL, `attr4` varchar(200) DEFAULT NULL www.percona.com
  • 18. #2: solution SELECT ta.*, SELECT ta.*, tb.attr1, tb.attr1, tb.attr2, tb.attr2, tn.attr3, tn.attr3, tb.attr4, tb.attr4, tc.attr1 tc.attr1 FROM table_a ta, FROM table_a ta, table_b tb, table_b tb, table_c tc table_c tc WHERE tb.ID = ta.tb_id WHERE tb.ID = ta.tb_id AND tc.attr1 = ta.attr1 AND tc.attr1 = ta.attr1 AND tc.attr2 = 1 AND tc.attr2 = 1 AND ta.attr3 = 'non_selective' AND ta.attr3 = 'non_selective' AND ta.attr4 = 715988 AND ta.attr4 = '715988' AND ta.attr5 BETWEEN 1 AND 10 AND ta.attr5 BETWEEN 1 AND 10 ORDER BY a.date_recorded ASC ORDER BY a.date_recorded ASC After this change, the right index is used (changing column type could be better) www.percona.com
  • 19. #2: conclusion ● Always quote strings, never quote numbers ● Similar thing can happen when there is a data type mismatch between joined tables ● For example an id is in a INT column is one table, VARCHAR(x) in the other, join won't use indexes on them www.percona.com
  • 21. #3: Query SELECT * FROM things WHERE ((thing_id=87459234 AND thing_flag1 = 1) OR (thing_other_thing_id=87459234 AND thing_flag2 = 1)) AND (thing_id=87459234 OR other_thing_id=87459234) AND (thing_id <> 3846571 AND other_thing_id <> 3846571) AND (thing_prop1 IS NOT NULL) AND (thing_rangedate >= '2012-12-01') OR (thing_rangedate_min > '2012-12-03' AND thing_rangedate_max < '2012-12-04') AND (NOT EXISTS (SELECT 1 FROM thing_stuffs WHERE fk_things_id = things.id AND important_num BETWEEN 1 and 4 AND other_range_value between 1 and 3)); If a query is big enough, always start with formatting the query. www.percona.com
  • 22. #3: Query SELECT * FROM things First issue is clear from WHERE explain output: ((thing_id=87459234 AND thing_flag1 = 1) DEPENDENT SUBQUERY OR (thing_other_thing_id=87459234 AND thing_flag2 = 1)) AND (thing_id=87459234 OR other_thing_id=87459234) AND (thing_id <> 3846571 AND other_thing_id <> 3846571) AND (thing_prop1 IS NOT NULL) AND (thing_rangedate >= '2012-12-01') OR (thing_rangedate_min > '2012-12-03' AND thing_rangedate_max < '2012-12-04') AND (NOT EXISTS (SELECT 1 FROM thing_stuffs WHERE fk_things_id = things.id AND important_num BETWEEN 1 and 4 AND other_range_value BETWEEN 1 and 3)); www.percona.com
  • 23. #3: Explain *************************** 1. row *************************** id: 1 select_type: PRIMARY table: things type: ref possible_keys: idx_thing_id,idx_other_thing_id,idx_prop1 key: idx_thing_id key_len: 4 rows: 23917933 Extra: Using where *************************** 2. row *************************** id: 2 select_type: DEPENDENT SUBQUERY table: thing_stuffs type: subquery possible_keys: PRIMARY,fk_things_id key: PRIMARY key_len: 4 rows: 1 Extra: Using where 2 rows in set (0.01 sec) www.percona.com
  • 24. #3: Rewrite DEPENDENT SUBQUERY SELECT * FROM things WHERE AND (NOT EXISTS (SELECT 1 FROM thing_stuffs WHERE fk_things_id = things.id AND important_num BETWEEN 1 and 4 AND other_range_value BETWEEN 1 and 3)); SELECT t.* FROM things t LEFT JOIN thing_stuffs ts ON ts.fk_things_id = things.id WHERE ts.fk_things_id IS NULL AND ts.important_num BETWEEN 1 AND 4 AND ts.other_range_value BETWEEN 1 AND 3 www.percona.com
  • 25. #3: Explain after rewrite *************************** 1. row *************************** id: 1 select_type: SIMPLE Composite index on important_num table: ts and other_range_value type: ref possible_keys: idx_important_num_other_range key: idx_important_num_other_range key_len: 4 ref: const rows: 93854 Extra: Using where *************************** 2. row *************************** id: 1 select_type: SIMPLE table: t type: ref possible_keys: PRIMARY key: PRIMARY key_len: 4 ref: ts.fk_things_id rows: 5 Extra: Using where 2 rows in set (0.01 sec) www.percona.com
  • 26. #3: Examining further Still more rows examined than returned. possible_keys: idx_important_num_other_range key: idx_important_num_other_range key_len: 4 rows: 93854 The index is a composite index, however only important_num is used mysql> SELECT COUNT(1) FROM thing_stuffs WHERE important_num BETWEEN 1 AND 4; +----------+ | count(1) | +----------+ | 87520 | +----------+ 1 row in set (0.15 sec) mysql> SELECT COUNT(1) FROM thing_stuffs WHERE other_range_value BETWEEN 1 AND 3; +----------+ | count(1) | +----------+ | 134526 | +----------+ 1 row in set (0.17 sec) www.percona.com
  • 27. #3: Examining further mysql> SELECT COUNT(1) FROM thing_stuff WHERE important_num BETWEEN 1 AND 4 AND other_range_value BETWEEN 1 AND 3; +----------+ | count(1) | +----------+ | 125 | +----------+ 1 row in set (0.15 sec) ● Together they are selective ● Both of them are range conditions, so they can't be used together in a composite index ● Unless we rewrite www.percona.com
  • 28. #3: Second rewrite SELECT COUNT(1) from thing_stuff WHERE important_num IN (1,2,3,4) AND other_range_value IN (1,2,3); *************************** 1. row *************************** id: 1 select_type: SIMPLE table: ts type: ref key: idx_important_num_other_range key_len: 8 ref: const rows: 125 Extra: Using where *************************** 2. row *************************** id: 1 select_type: SIMPLE table: t type: ref key: PRIMARY key_len: 4 ref: ts.fk_things_id rows: 5 Extra: Using where 2 rows in set (0.01 sec) www.percona.com
  • 29. #3: Using it in the original query The query is still slow. SELECT t.* FROM things t LEFT JOIN thing_stuffs ts ON ts.fk_things_id = t.id A lot more rows examined WHERE ((t.thing_id=87459234 AND t.thing_flag1 = 1) Than returned. OR (t.other_thing_id=87459234 AND t.thing_flag2 = 1)) AND (t.thing_id=87459234 OR t.other_thing_id=87459234) AND (t.thing_id <> 3846571 Checking explain the AND t.other_thing_id <> 3846571) relevant part is that the AND (t.thing_prop1 IS NOT NULL) query uses an index merge. AND (t.thing_rangedate >= '2012-12-01') OR (t.thing_rangedate_min > '2012-12-03' AND t.thing_rangedate_max < '2012-12-04') AND ts.important_num IN (1,2,3,4) AND ts.other_range_value IN (1,2,3) AND ts.fk_things_id IS NULL; Extra: Using union(idx_thing_id,idx_other_thing_id); Using where www.percona.com
  • 30. #3: Relevant part SELECT * FROM things WHERE (thing_id=87459234 OR other_thing_id=87459234) AND thing_id <> 3846571 AND other_thing_id <> 3846571; *************************** 1. row *************************** id: 1 select_type: SIMPLE table: things type: index_merge possible_keys: idx_thing_id,idx_other_thing_id key: idx_thing_id,idx_other_thing_id key_len: 4,4 ref: NULL rows: 59834 Extra: Using union(idx_thing_id,idx_other_thing_id); Using where 1 row in set (0.00 sec) www.percona.com
  • 31. #3: Rewritten query ● Index merge is an expensive SELECT * FROM things operation WHERE thing_id=87459234 AND other_thing_id<>3846571 ● Especially if indexes are large UNION SELECT * FROM things ● UNION always create an on-disk WHERE other_thing_id=87459234 temp table AND thing_id<>3846571; ● Just turning off index merge could be enough for a significant performance advantage mysql> select @@optimizer_switchG *************************** 1. row *************************** @@optimizer_switch: index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_interse ction=on,engine_condition_pushdown=on 1 row in set (0.00 sec) www.percona.com
  • 32. #3: Putting it together SELECT t.* FROM things t LEFT JOIN things_stuff ts ON ts.fk_things_id = t.id WHERE t.thing_id=87459234 AND t.other_thing_id<>3846571 AND t.thing_flag1=1 AND t.thing_prop IS NOT NULL SELECT t.* FROM things t AND (t.thing_rangedate_min >= '2012-12-01') LEFT JOIN t.things_stuff ts AND ((t.thing_rangedate_min <= '2012-12-03' ON ts.fk_things_id = t.id AND t.thing_rangedate_max > '2012-12-03') WHERE t.other_thing_id=87459234 OR (t.thing_rangedate_min < '2012-12-04' AND t.thing_id<>3846571 AND t.thing_rangedate_max >= '2012-12-04') AND t.thing_flag2=1 OR (t.thing_rangedate_min > '2012-12-03' AND t.thing_prop1 IS NOT NULL AND t.thing_rangerate_max < '2012-12-04')) AND (t.thing_rangedate_min >= '2012-12-01') AND ts.fk_things_id IS NULL AND ((t.thing_rangedate_min <= '2012-12-03' AND ts.important_num IN (1,2,3,4) AND t.thing_rangedate_max > '2012-12-03') AND ts.other_range_value IN (1,2,3) OR (t.thing_rangedate_min < '2012-12-04' UNION AND t.thing_rangedate_max >= '2012-12-04') OR (t.thing_rangedate_min > '2012-12-03' AND t.thing_rangedate_max < '2012-12-04')) AND ts.fk_things_id IS NULL AND ts.important_num IN (1,2,3,4) AND ts.other_range_value IN (1,2,3); www.percona.com
  • 34. #4: Summary ● Very large, 20 table join ● Explain looks ok ● Query runs for almost a hour ● Handler status variables are way off www.percona.com
  • 35. #4: Query SELECT tmain.id, tmain.date, CONCAT_WS("_", COALESCE(m1.col1, 'n/a'), COALESCE(m2.col2, 'n/a') /* a lot more columns selected */) FROM main_table as tmain ah LEFT JOIN (metadata_table1 m1 JOIN metadata_table2 m2 ON m1.attr1 = m2.attr1 AND m1.const = 'some text') ON tmain.id = m1.tmain_id AND tmain.important_flag=1 AND ((m1.attr11='a') OR (m2.attr12 IS NOT NULL) AND 3>=m1.attr13 AND 5<m2.attr14) OR m1.attr15 IS NOT NULL AND m2.attr16 BETWEEN 1 AND 10 LEFT JOIN (metadata_table3 m3 JOIN metadata_table4 m4 ON m3.attr1 = m4.attr1 AND m1.const = 'some text') ON tmain.id = m4.tmain_id AND tmain.important_flag=1 AND ((m3.attr11='a') OR (m4.attr12 IS NOT NULL) AND 3>=m3.attr13 AND 5<m4.attr14) OR m3.attr15 IS NOT NULL AND m4.attr16 BETWEEN 11 AND 20 LEFT JOIN (metadata_table5 m5 JOIN metadata_table2 m6 ON m5.attr1 = m6.attr1 AND m1.const = 'some text') ON tmain.id = m5.tmain_id AND tmain.important_flag=1 AND ((m5.attr11='a') OR (m6.attr12 IS NOT NULL) AND 3>=m5.attr13 AND 5<m6.attr14) OR m1.attr15 IS NOT NULL AND m2.attr16 BETWEEN 21 AND 30 LEFT JOIN (metadata_table1 m7 JOIN metadata_table2 m8 ON m7.attr1 = m8.attr1 AND m7.const = 'some text') ON tmain.id = m7.tmain_id AND tmain.important_flag=1 AND ((m7.attr11='a') OR (m8.attr12 IS NOT NULL) AND 3>=m7.attr13 AND 5<m8.attr14) OR m7.attr15 IS NOT NULL AND m8.attr16 BETWEEN 31 AND 40 /* 6 more joins exactly like the previous ones... */ WHERE tmain.important_flag = 1; www.percona.com
  • 36. #4: Explain (only relevant part) +----+-------------+----------+--------+------+-------------+ | id | select_type | table | type | rows | Extra | +----+-------------+----------+--------+------+-------------+ | 1 | SIMPLE | tmain | ref | 1786 | | | 1 | SIMPLE | m1 | ref | 4 | | | 1 | SIMPLE | m2 | eq_ref | 1 | Using index | | 1 | SIMPLE | m3 | ref | 4 | | | 1 | SIMPLE | m4 | eq_ref | 1 | Using index | |....|.............|..........|........|......|.............| | 1 | SIMPLE | m19 | ref | 4 | | | 1 | SIMPLE | m20 | eq_ref | 1 | Using index | +----+-------------+----------+--------+------+-------------+ www.percona.com
  • 37. #4: Handler operations mysql> show status like 'Handler%'; +----------------------------+-----------+ Run FLUSH STATUS before the query | Variable_name | Value | +----------------------------+-----------+ to reset the counters. | Handler_commit | 1 | | Handler_delete | 0 | | Handler_discover | 0 | FLUSH STATUS; | Handler_prepare | 0 | QUERY; | Handler_read_first | 0 | | Handler_read_key | 61341 | SHOW STATUS LIKE 'Handler%'; | Handler_read_last | 0 | | Handler_read_next | 198008370 | | Handler_read_prev | 0 | | Handler_read_rnd | 0 | | Handler_read_rnd_next | 0 | | Handler_rollback | 0 | | Handler_savepoint | 0 | | Handler_savepoint_rollback | 0 | | Handler_update | 0 | | Handler_write | 0 | +----------------------------+-----------+ www.percona.com
  • 38. #4: Problematic part LEFT JOIN (metadata_table1 m7 JOIN metadata_table2 m8 ON m7.attr1 = m8.attr1 AND m7.const = 'some text') ON tmain.id = m7.tmain_id AND tmain.important_flag=1; SELECT AVG(LENGTH(m1.somefield)) FROM metadata_table1 m1 JOIN metadata_table2 m2 ON m1.attr1 = m2.attr1 AND m1.const='some text' +----+-------------+----------+--------+-------+-------------+ | id | select_type | table | type | rows | Extra | +----+-------------+----------+--------+-------+-------------+ | 1 | SIMPLE | m1 | ref | 19764 | | | 1 | SIMPLE | m2 | eq_ref | 102 | Using index | +----+-------------+----------+--------+-------+-------------+ MySQL executes the join like this. One “problematic part takes roughly 3 minutes, so It adds up. www.percona.com
  • 39. #4: Rewrite SELECT tmain.id FROM main_table tmain LEFT JOIN metadata_table1 m1 ON tmain.id=m1.tmain_id LEFT JOIN metadata_table2 m2 ON m1.attr1 = m2.attr1 AND m1.const = 'some text' WHERE tmain.important_flag = 1; ● In order to leave out () LEFT JOIN has to be used to find non-matching elements. ● Runtime for query is 0.2 sec instead of 3 minutes. +----+-------------+----------+--------+------+-------------+ | id | select_type | table | type | rows | Extra | +----+-------------+----------+--------+------+-------------+ | 1 | SIMPLE | tmain | ref | 1786 | | | 1 | SIMPLE | m1 | ref | 4 | | | 1 | SIMPLE | m2 | eq_ref | 1 | Using index | +----+-------------+----------+--------+------+-------------+ www.percona.com
  • 40. #4: Similarly large queries ● After applying the tuning to the original query, I expected it t execute in a few seconds. ● It executed in 4 minutes instead. ● Used Handler operations looked good. ● Took a look at explain, and explain took 4 minutes also. ● This means the optimizer spends time in constructing the query plan. ● Solution: STRAIGHT_JOIN and/or optimizer_search_depth www.percona.com
  • 41. Annual Percona Live MySQL Conference and Expo Visit: http://www.percona.com/live/mysql-conference-2013/ www.percona.com
  • 42. Q&A
  • 43. Thank you for attention.