Hello up there MariaDB team,
I'm currently debugging performance anomalies in MariaDB under NEO,
when same queries are usually executed fast, but sometimes badly slow. I've
discovered that some (not all) of such cases happen because wrong query
execution plan is somehow selected by optimizer. Why optimizer makes such
decision is a question.
For simple cases in a couple of times we can hopefully paper the problem over
with things like FORCE INDEX, but since this issue is starting to appear
regularly in many different places it is better to understand the root cause
and fix problem there.
That's where optimizer trace would be very handy - to get info from the system
about why such-and-such query execution decision has been made. With this
message I'd like to provide to MariaDB team feedback that optimizer trace is
needed in real-life since on production instances we cannot use debug builds
and get info from DBUG.
I provide examples of some anomalies in appendix for the reference.
Thanks beforehand,
Kirill
P.S. My familiarity with MariaDB is only several days, so please forgive me in
advance some possibly silly mistakes.
/cc ratzpo (@ratzpo)
Appendix
MariaDB 10.1.17. TokuDB is used as storage engine.
Example of bad query caught in slow log:
# Time: 160921 10:47:15
|
# User@Host: root[root] @ localhost []
|
# Thread_id: 6 Schema: neo1 QC_hit: No
|
# Query_time: 4.118192 Lock_time: 0.000024 Rows_sent: 0 Rows_examined: 8476058
|
# Rows_affected: 0
|
#
|
# explain: id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
|
# explain: 1 SIMPLE obj ref PRIMARY,partition partition 10 const,const 1 8476058.00 100.00 0.00 Using where; Using index
|
#
|
SET timestamp=1474447635;
|
SELECT tid FROM obj WHERE `partition`=5 AND oid=79613 AND tid>268544235197088772 ORDER BY tid LIMIT 1;
|
Similar query caught in process list with analyze:
MariaDB [neo1]> show processlist;
|
+----+------+-----------+------+---------+------+----------------------------+------------------------------------------------------------------------------------------------------+----------+
|
| Id | User | Host | db | Command | Time | State | Info | Progress |
|
+----+------+-----------+------+---------+------+----------------------------+------------------------------------------------------------------------------------------------------+----------+
|
| 3 | root | localhost | neo0 | Sleep | 8 | | NULL | 0.000 |
|
| 4 | root | localhost | neo2 | Sleep | 15 | | NULL | 0.000 |
|
| 5 | root | localhost | neo3 | Sleep | 11 | | NULL | 0.000 |
|
| 6 | root | localhost | neo1 | Query | 3 | Queried about 7710000 rows | SELECT tid FROM obj WHERE `partition`=5 AND oid=79613 AND tid>268544341634012678 ORDER BY tid LIMIT | 0.000 |
|
| 10 | root | localhost | neo1 | Query | 0 | init | show processlist | 0.000 |
|
+----+------+-----------+------+---------+------+----------------------------+------------------------------------------------------------------------------------------------------+----------+
|
5 rows in set (0.00 sec)
|
|
MariaDB [neo1]> show explain for 6;
|
+------+-------------+-------+------+-------------------+-----------+---------+-------------+------+------------------------------------------+
|
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
|
+------+-------------+-------+------+-------------------+-----------+---------+-------------+------+------------------------------------------+
|
| 1 | SIMPLE | obj | ref | PRIMARY,partition | partition | 10 | const,const | 1 | Using where; Using index; Using filesort |
|
+------+-------------+-------+------+-------------------+-----------+---------+-------------+------+------------------------------------------+
|
1 row in set, 1 warning (0.01 sec)
|
The same query in normal case:
MariaDB [neo1]> explain SELECT tid FROM obj WHERE `partition`=5 AND oid=79613 AND tid>268544341634012678 ORDER BY tid LIMIT 1;
|
+------+-------------+-------+-------+-------------------+-----------+---------+------+------+--------------------------+
|
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
|
+------+-------------+-------+-------+-------------------+-----------+---------+------+------+--------------------------+
|
| 1 | SIMPLE | obj | range | PRIMARY,partition | partition | 18 | NULL | 1295 | Using where; Using index |
|
+------+-------------+-------+-------+-------------------+-----------+---------+------+------+--------------------------+
|
1 row in set (0.00 sec)
|
|
MariaDB [neo1]> analyze SELECT tid FROM obj WHERE `partition`=5 AND oid=79613 AND tid>268544341634012678 ORDER BY tid LIMIT 1;
|
+------+-------------+-------+-------+-------------------+-----------+---------+------+------+--------+----------+------------+--------------------------+
|
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | r_rows | filtered | r_filtered | Extra |
|
+------+-------------+-------+-------+-------------------+-----------+---------+------+------+--------+----------+------------+--------------------------+
|
| 1 | SIMPLE | obj | range | PRIMARY,partition | partition | 18 | NULL | 639 | 1.00 | 100.00 | 100.00 | Using where; Using index |
|
+------+-------------+-------+-------+-------------------+-----------+---------+------+------+--------+----------+------------+--------------------------+
|
1 row in set (0.00 sec)
|
|
MariaDB [neo1]> SELECT tid FROM obj WHERE `partition`=5 AND oid=79613 AND tid>268544341634012678 ORDER BY tid LIMIT 1;
|
+--------------------+
|
| tid |
|
+--------------------+
|
| 268544342862377552 |
|
+--------------------+
|
1 row in set (0.00 sec)
|
NOTE the difference:
- time: 4s vs < 0.01s
- type: 'ref' vs 'range'
- key_len: 10 vs 18 (partition, oid) vs (partition, oid, tid)
- ref: const,const vs NULL
- "Using filesort"
For the reference:
MariaDB [neo1]> describe obj;
|
+-----------+----------------------+------+-----+---------+-------+
|
| Field | Type | Null | Key | Default | Extra |
|
+-----------+----------------------+------+-----+---------+-------+
|
| partition | smallint(5) unsigned | NO | PRI | NULL | |
|
| oid | bigint(20) unsigned | NO | PRI | NULL | |
|
| tid | bigint(20) unsigned | NO | PRI | NULL | |
|
| data_id | bigint(20) unsigned | YES | MUL | NULL | |
|
| value_tid | bigint(20) unsigned | YES | | NULL | |
|
+-----------+----------------------+------+-----+---------+-------+
|
5 rows in set (0.00 sec)
|
|
MariaDB [neo1]> show index from obj;
|
+-------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
|
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
|
+-------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
|
| obj | 0 | PRIMARY | 1 | partition | A | 28253069 | NULL | NULL | | BTREE | | |
|
| obj | 0 | PRIMARY | 2 | tid | A | 28253069 | NULL | NULL | | BTREE | | |
|
| obj | 0 | PRIMARY | 3 | oid | A | 28253069 | NULL | NULL | | BTREE | | |
|
| obj | 1 | partition | 1 | partition | A | 28253069 | NULL | NULL | | BTREE | | |
|
| obj | 1 | partition | 2 | oid | A | 28253069 | NULL | NULL | | BTREE | | |
|
| obj | 1 | partition | 3 | tid | A | 28253069 | NULL | NULL | | BTREE | | |
|
| obj | 1 | data_id | 1 | data_id | A | 28253069 | NULL | NULL | YES | BTREE | | |
|
+-------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
|
7 rows in set (0.01 sec)
|
|
MariaDB [neo1]> show table status like 'obj'\G
|
*************************** 1. row ***************************
|
Name: obj
|
Engine: TokuDB
|
Version: 10
|
Row_format: Fixed
|
Rows: 28253276
|
Avg_row_length: 33
|
Data_length: 957477808
|
Max_data_length: 9223372036854775807
|
Index_length: 1779148337
|
Data_free: 913293312
|
Auto_increment: NULL
|
Create_time: 2016-08-16 10:33:02
|
Update_time: 2016-09-21 22:05:35
|
Check_time: NULL
|
Collation: utf8_unicode_ci
|
Checksum: NULL
|
Create_options:
|
Comment:
|
1 row in set (0.00 sec)
|
Another example:
https://lab.nexedi.com/nexedi/neoppod/commit/13911ca3
Hello up there MariaDB team,
I'm currently debugging performance anomalies in MariaDB under NEO,
when same queries are usually executed fast, but sometimes badly slow. I've
discovered that some (not all) of such cases happen because wrong query
execution plan is somehow selected by optimizer. Why optimizer makes such
decision is a question.
For simple cases in a couple of times we can hopefully paper the problem over
with things like FORCE INDEX, but since this issue is starting to appear
regularly in many different places it is better to understand the root cause
and fix problem there.
That's where optimizer trace would be very handy - to get info from the system
about why such-and-such query execution decision has been made. With this
message I'd like to provide to MariaDB team feedback that optimizer trace is
needed in real-life since on production instances we cannot use debug builds
and get info from DBUG.
I provide examples of some anomalies in appendix for the reference.
Thanks beforehand,
Kirill
P.S. My familiarity with MariaDB is only several days, so please forgive me in
advance some possibly silly mistakes.
/cc ratzpo (@ratzpo)
Appendix
MariaDB 10.1.17. TokuDB is used as storage engine.
Example of bad query caught in slow log:
# Time: 160921 10:47:15
# User@Host: root[root] @ localhost []
# Thread_id: 6 Schema: neo1 QC_hit: No
# Query_time: 4.118192 Lock_time: 0.000024 Rows_sent: 0 Rows_examined: 8476058
# Rows_affected: 0
#
# explain: id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
# explain: 1 SIMPLE obj ref PRIMARY,partition partition 10 const,const 1 8476058.00 100.00 0.00 Using where; Using index
#
SET timestamp=1474447635;
SELECT tid FROM obj WHERE `partition`=5 AND oid=79613 AND tid>268544235197088772 ORDER BY tid LIMIT 1;
Similar query caught in process list with analyze:
MariaDB [neo1]> show processlist;
+----+------+-----------+------+---------+------+----------------------------+------------------------------------------------------------------------------------------------------+----------+
| Id | User | Host | db | Command | Time | State | Info | Progress |
+----+------+-----------+------+---------+------+----------------------------+------------------------------------------------------------------------------------------------------+----------+
| 3 | root | localhost | neo0 | Sleep | 8 | | NULL | 0.000 |
| 4 | root | localhost | neo2 | Sleep | 15 | | NULL | 0.000 |
| 5 | root | localhost | neo3 | Sleep | 11 | | NULL | 0.000 |
| 6 | root | localhost | neo1 | Query | 3 | Queried about 7710000 rows | SELECT tid FROM obj WHERE `partition`=5 AND oid=79613 AND tid>268544341634012678 ORDER BY tid LIMIT | 0.000 |
| 10 | root | localhost | neo1 | Query | 0 | init | show processlist | 0.000 |
+----+------+-----------+------+---------+------+----------------------------+------------------------------------------------------------------------------------------------------+----------+
5 rows in set (0.00 sec)
MariaDB [neo1]> show explain for 6;
+------+-------------+-------+------+-------------------+-----------+---------+-------------+------+------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+------+-------------------+-----------+---------+-------------+------+------------------------------------------+
| 1 | SIMPLE | obj | ref | PRIMARY,partition | partition | 10 | const,const | 1 | Using where; Using index; Using filesort |
+------+-------------+-------+------+-------------------+-----------+---------+-------------+------+------------------------------------------+
1 row in set, 1 warning (0.01 sec)
The same query in normal case:
MariaDB [neo1]> explain SELECT tid FROM obj WHERE `partition`=5 AND oid=79613 AND tid>268544341634012678 ORDER BY tid LIMIT 1;
+------+-------------+-------+-------+-------------------+-----------+---------+------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+-------+-------------------+-----------+---------+------+------+--------------------------+
| 1 | SIMPLE | obj | range | PRIMARY,partition | partition | 18 | NULL | 1295 | Using where; Using index |
+------+-------------+-------+-------+-------------------+-----------+---------+------+------+--------------------------+
1 row in set (0.00 sec)
MariaDB [neo1]> analyze SELECT tid FROM obj WHERE `partition`=5 AND oid=79613 AND tid>268544341634012678 ORDER BY tid LIMIT 1;
+------+-------------+-------+-------+-------------------+-----------+---------+------+------+--------+----------+------------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | r_rows | filtered | r_filtered | Extra |
+------+-------------+-------+-------+-------------------+-----------+---------+------+------+--------+----------+------------+--------------------------+
| 1 | SIMPLE | obj | range | PRIMARY,partition | partition | 18 | NULL | 639 | 1.00 | 100.00 | 100.00 | Using where; Using index |
+------+-------------+-------+-------+-------------------+-----------+---------+------+------+--------+----------+------------+--------------------------+
1 row in set (0.00 sec)
MariaDB [neo1]> SELECT tid FROM obj WHERE `partition`=5 AND oid=79613 AND tid>268544341634012678 ORDER BY tid LIMIT 1;
+--------------------+
| tid |
+--------------------+
| 268544342862377552 |
+--------------------+
1 row in set (0.00 sec)
NOTE the difference:
For the reference:
MariaDB [neo1]> describe obj;
+-----------+----------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+----------------------+------+-----+---------+-------+
| partition | smallint(5) unsigned | NO | PRI | NULL | |
| oid | bigint(20) unsigned | NO | PRI | NULL | |
| tid | bigint(20) unsigned | NO | PRI | NULL | |
| data_id | bigint(20) unsigned | YES | MUL | NULL | |
| value_tid | bigint(20) unsigned | YES | | NULL | |
+-----------+----------------------+------+-----+---------+-------+
5 rows in set (0.00 sec)
MariaDB [neo1]> show index from obj;
+-------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| obj | 0 | PRIMARY | 1 | partition | A | 28253069 | NULL | NULL | | BTREE | | |
| obj | 0 | PRIMARY | 2 | tid | A | 28253069 | NULL | NULL | | BTREE | | |
| obj | 0 | PRIMARY | 3 | oid | A | 28253069 | NULL | NULL | | BTREE | | |
| obj | 1 | partition | 1 | partition | A | 28253069 | NULL | NULL | | BTREE | | |
| obj | 1 | partition | 2 | oid | A | 28253069 | NULL | NULL | | BTREE | | |
| obj | 1 | partition | 3 | tid | A | 28253069 | NULL | NULL | | BTREE | | |
| obj | 1 | data_id | 1 | data_id | A | 28253069 | NULL | NULL | YES | BTREE | | |
+-------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
7 rows in set (0.01 sec)
MariaDB [neo1]> show table status like 'obj'\G
*************************** 1. row ***************************
Name: obj
Engine: TokuDB
Version: 10
Row_format: Fixed
Rows: 28253276
Avg_row_length: 33
Data_length: 957477808
Max_data_length: 9223372036854775807
Index_length: 1779148337
Data_free: 913293312
Auto_increment: NULL
Create_time: 2016-08-16 10:33:02
Update_time: 2016-09-21 22:05:35
Check_time: NULL
Collation: utf8_unicode_ci
Checksum: NULL
Create_options:
Comment:
1 row in set (0.00 sec)
Another example:
https://lab.nexedi.com/nexedi/neoppod/commit/13911ca3