Details
-
Bug
-
Status: Closed (View Workflow)
-
Major
-
Resolution: Fixed
-
5.5.39, 10.0.13
-
10.0.20
Description
Using the attached mysqldump, the following query is very slow in MariaDB compared to MySQL 5.5 or MySQL 5.6:
SELECT 1 FROM `catalog_category_flat_store_1` AS `main_table` |
LEFT JOIN `core_url_rewrite` AS `url_rewrite` |
ON url_rewrite.category_id=main_table.entity_id |
AND url_rewrite.is_system=1 |
AND url_rewrite.store_id = 1 |
AND url_rewrite.id_path LIKE 'category/%' |
WHERE (main_table.include_in_menu = '1') |
AND (main_table.is_active = '1') |
AND (main_table.path like '1/2/%') |
ORDER BY `main_table`.`position` ASC |
The schema and query are part of Magento, but the attached dump has had FK, some unique indexes, and most of the columns dropped.
The query plan in MySQL, which executes quickly:
| 1 | SIMPLE | main_table | ALL | IDX_CATALOG_CATEGORY_FLAT_STORE_1_PATH | NULL | NULL | NULL | 124 | Using where; Using temporary; Using filesort |
|
| 1 | SIMPLE | url_rewrite | range | UNQ_CORE_URL_REWRITE_ID_PATH_IS_SYSTEM_STORE_ID,IDX_CORE_URL_REWRITE_ID_PATH,IDX_CORE_URL_REWRITE_STORE_ID,FK_CORE_URL_REWRITE_CTGR_ID_CAT_CTGR_ENTT_ENTT_ID | UNQ_CORE_URL_REWRITE_ID_PATH_IS_SYSTEM_STORE_ID | 773 | NULL | 1138 | Using where |
|
5.6 has BNL and using Join buffer for the second table, and runs at a similar speed.
In MariaDB 5.5 and MariaDB 10, the following slow plan is used:
| 1 | SIMPLE | main_table | ALL | IDX_CATALOG_CATEGORY_FLAT_STORE_1_PATH | NULL | NULL | NULL | 149 | Using where; Using filesort |
|
| 1 | SIMPLE | url_rewrite | range | UNQ_CORE_URL_REWRITE_ID_PATH_IS_SYSTEM_STORE_ID,IDX_CORE_URL_REWRITE_ID_PATH,IDX_CORE_URL_REWRITE_STORE_ID,FK_CORE_URL_REWRITE_CTGR_ID_CAT_CTGR_ENTT_ENTT_ID | UNQ_CORE_URL_REWRITE_ID_PATH_IS_SYSTEM_STORE_ID | 773 | NULL | 1138 | Range checked for each record (index map: 0x74) |
|
This can be made fast in MariaDB with ADD INDEX ix_foo (category_id, store_id) or IGNORE INDEX.
There also seems to be no optimizer_switch to turn off this strategy.
Attachments
Issue Links
Activity
Field | Original Value | New Value |
---|---|---|
Assignee | Elena Stepanova [ elenst ] |
Fix Version/s | 10.0 [ 16000 ] |
Assignee | Elena Stepanova [ elenst ] | Sergei Petrunia [ psergey ] |
Description |
Using the attached mysqldump, the following query is very slow in MariaDB compared to MySQL 5.5 or MySQL 5.6: SELECT 1 FROM `catalog_category_flat_store_1` AS `main_table` LEFT JOIN `core_url_rewrite` AS `url_rewrite` ON url_rewrite.category_id=main_table.entity_id AND url_rewrite.is_system=1 AND url_rewrite.store_id = 1 AND url_rewrite.id_path LIKE 'category/%' WHERE (main_table.include_in_menu = '1') AND (main_table.is_active = '1') AND (main_table.path like '1/2/%') ORDER BY `main_table`.`position` ASC The schema and query are part of Magento, but the attached dump has had FK, some unique indexes, and most of the columns dropped. The query plan in MySQL, which executes quickly: | 1 | SIMPLE | main_table | ALL | IDX_CATALOG_CATEGORY_FLAT_STORE_1_PATH | NULL | NULL | NULL | 124 | Using where; Using temporary; Using filesort | | 1 | SIMPLE | url_rewrite | range | UNQ_CORE_URL_REWRITE_ID_PATH_IS_SYSTEM_STORE_ID,IDX_CORE_URL_REWRITE_ID_PATH,IDX_CORE_URL_REWRITE_STORE_ID,FK_CORE_URL_REWRITE_CTGR_ID_CAT_CTGR_ENTT_ENTT_ID | UNQ_CORE_URL_REWRITE_ID_PATH_IS_SYSTEM_STORE_ID | 773 | NULL | 1138 | Using where | 5.6 has BNL and using Join buffer for the second table, and runs at a similar speed. In MariaDB 5.5 and MariaDB 10, the following slow plan is used: | 1 | SIMPLE | main_table | ALL | IDX_CATALOG_CATEGORY_FLAT_STORE_1_PATH | NULL | NULL | NULL | 149 | Using where; Using filesort | | 1 | SIMPLE | url_rewrite | range | UNQ_CORE_URL_REWRITE_ID_PATH_IS_SYSTEM_STORE_ID,IDX_CORE_URL_REWRITE_ID_PATH,IDX_CORE_URL_REWRITE_STORE_ID,FK_CORE_URL_REWRITE_CTGR_ID_CAT_CTGR_ENTT_ENTT_ID | UNQ_CORE_URL_REWRITE_ID_PATH_IS_SYSTEM_STORE_ID | 773 | NULL | 1138 | Range checked for each record (index map: 0x74) | This can be made fast in MariaDB with ADD INDEX ix_foo (category_id, store_id) or IGNORE INDEX. There also seems to be no optimizer_switch to turn off this strategy. |
Using the attached mysqldump, the following query is very slow in MariaDB compared to MySQL 5.5 or MySQL 5.6: {code:sql} SELECT 1 FROM `catalog_category_flat_store_1` AS `main_table` LEFT JOIN `core_url_rewrite` AS `url_rewrite` ON url_rewrite.category_id=main_table.entity_id AND url_rewrite.is_system=1 AND url_rewrite.store_id = 1 AND url_rewrite.id_path LIKE 'category/%' WHERE (main_table.include_in_menu = '1') AND (main_table.is_active = '1') AND (main_table.path like '1/2/%') ORDER BY `main_table`.`position` ASC {code} The schema and query are part of Magento, but the attached dump has had FK, some unique indexes, and most of the columns dropped. The query plan in MySQL, which executes quickly: {noformat} | 1 | SIMPLE | main_table | ALL | IDX_CATALOG_CATEGORY_FLAT_STORE_1_PATH | NULL | NULL | NULL | 124 | Using where; Using temporary; Using filesort | | 1 | SIMPLE | url_rewrite | range | UNQ_CORE_URL_REWRITE_ID_PATH_IS_SYSTEM_STORE_ID,IDX_CORE_URL_REWRITE_ID_PATH,IDX_CORE_URL_REWRITE_STORE_ID,FK_CORE_URL_REWRITE_CTGR_ID_CAT_CTGR_ENTT_ENTT_ID | UNQ_CORE_URL_REWRITE_ID_PATH_IS_SYSTEM_STORE_ID | 773 | NULL | 1138 | Using where | {noformat} 5.6 has BNL and using Join buffer for the second table, and runs at a similar speed. In MariaDB 5.5 and MariaDB 10, the following slow plan is used: {noformat} | 1 | SIMPLE | main_table | ALL | IDX_CATALOG_CATEGORY_FLAT_STORE_1_PATH | NULL | NULL | NULL | 149 | Using where; Using filesort | | 1 | SIMPLE | url_rewrite | range | UNQ_CORE_URL_REWRITE_ID_PATH_IS_SYSTEM_STORE_ID,IDX_CORE_URL_REWRITE_ID_PATH,IDX_CORE_URL_REWRITE_STORE_ID,FK_CORE_URL_REWRITE_CTGR_ID_CAT_CTGR_ENTT_ENTT_ID | UNQ_CORE_URL_REWRITE_ID_PATH_IS_SYSTEM_STORE_ID | 773 | NULL | 1138 | Range checked for each record (index map: 0x74) | {noformat} This can be made fast in MariaDB with ADD INDEX ix_foo (category_id, store_id) or IGNORE INDEX. There also seems to be no optimizer_switch to turn off this strategy. |
Component/s | Optimizer [ 10200 ] |
Attachment | MDEV-6735.patch [ 37484 ] |
Attachment | mdev-6735.sql [ 37485 ] |
Attachment | mdev-6735_x2_x1_testcase.sql.gz [ 37486 ] |
Comment |
[ smaller from private upload - still too much {noformat} MariaDB [test]> SET @newid=0;drop table if exists x4;create table x4 like x3; insert into x4 select * from x3 where MOD(@newid:=@newid+1,10)=0; ANALYZE TABLE x4 PERSISTENT FOR ALL; explain SELECT 1 FROM x1 LEFT JOIN x4 x2 ON x2.category_id=x1.entity_id AND x2.id_path LIKE 'category/%';delete from x4 where category_id is null and MOD(@newid:=@newid+1,4)!=0;analyze table x4 persistent for all; select * from mysql.index_stats where db_name='test' and table_name in ('x4'); explain SELECT 1 FROM x1 LEFT JOIN x4 x2 ON x2.category_id=x1.entity_id AND x2.id_path LIKE 'category/%'; Query OK, 0 rows affected (0.00 sec) Query OK, 0 rows affected (0.03 sec) Query OK, 0 rows affected (0.01 sec) Query OK, 113949 rows affected (2.58 sec) Records: 113949 Duplicates: 0 Warnings: 0 +---------+---------+----------+-----------------------------------------+ | Table | Op | Msg_type | Msg_text | +---------+---------+----------+-----------------------------------------+ | test.x4 | analyze | status | Engine-independent statistics collected | | test.x4 | analyze | status | OK | +---------+---------+----------+-----------------------------------------+ 2 rows in set (0.68 sec) +------+-------------+-------+-------+-------------------------------------------------------+---------+---------+------+--------+------------------------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +------+-------------+-------+-------+-------------------------------------------------------+---------+---------+------+--------+------------------------------------------------+ | 1 | SIMPLE | x1 | index | NULL | PRIMARY | 4 | NULL | 143 | Using index | | 1 | SIMPLE | x2 | ALL | FK_CORE_URL_REWRITE_CTGR_ID_CAT_CTGR_ENTT_ENTT_ID,idx | idx | 768 | NULL | 114738 | Range checked for each record (index map: 0x6) | +------+-------------+-------+-------+-------------------------------------------------------+---------+---------+------+--------+------------------------------------------------+ 2 rows in set (0.00 sec) Query OK, 64789 rows affected (0.66 sec) +---------+---------+----------+-----------------------------------------+ | Table | Op | Msg_type | Msg_text | +---------+---------+----------+-----------------------------------------+ | test.x4 | analyze | status | Engine-independent statistics collected | | test.x4 | analyze | status | OK | +---------+---------+----------+-----------------------------------------+ 2 rows in set (0.32 sec) +---------+------------+---------------------------------------------------+--------------+---------------+ | db_name | table_name | index_name | prefix_arity | avg_frequency | +---------+------------+---------------------------------------------------+--------------+---------------+ | test | x4 | FK_CORE_URL_REWRITE_CTGR_ID_CAT_CTGR_ENTT_ENTT_ID | 1 | 199.7391 | | test | x4 | FK_CORE_URL_REWRITE_CTGR_ID_CAT_CTGR_ENTT_ENTT_ID | 2 | 1.0000 | | test | x4 | PRIMARY | 1 | 1.0000 | | test | x4 | idx | 1 | 1.0342 | | test | x4 | idx | 2 | 1.0000 | +---------+------------+---------------------------------------------------+--------------+---------------+ 5 rows in set (0.00 sec) +------+-------------+-------+-------+-------------------------------------------------------+---------+---------+------+-------+------------------------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +------+-------------+-------+-------+-------------------------------------------------------+---------+---------+------+-------+------------------------------------------------+ | 1 | SIMPLE | x1 | index | NULL | PRIMARY | 4 | NULL | 143 | Using index | | 1 | SIMPLE | x2 | ALL | FK_CORE_URL_REWRITE_CTGR_ID_CAT_CTGR_ENTT_ENTT_ID,idx | idx | 768 | NULL | 44069 | Range checked for each record (index map: 0x6) | +------+-------------+-------+-------+-------------------------------------------------------+---------+---------+------+-------+------------------------------------------------+ 2 rows in set (0.00 sec) MariaDB [test]> select count(*) from x4; +----------+ | count(*) | +----------+ | 49160 | +----------+ {noformat} ] |
Workflow | MariaDB v2 [ 53832 ] | MariaDB v3 [ 62481 ] |
Sprint | 10.0.20 [ 5 ] |
Fix Version/s | 5.5.44 [ 19100 ] | |
Fix Version/s | 10.0 [ 16000 ] | |
Resolution | Fixed [ 1 ] | |
Status | Open [ 1 ] | Closed [ 6 ] |
Fix Version/s | 5.5.45 [ 19405 ] | |
Fix Version/s | 5.5.44 [ 19100 ] |
Fix Version/s | 10.0.21 [ 19406 ] |
Fix Version/s | 10.0.20 [ 19201 ] | |
Fix Version/s | 5.5.44 [ 19100 ] | |
Fix Version/s | 5.5.45 [ 19405 ] | |
Fix Version/s | 10.0.21 [ 19406 ] |
Workflow | MariaDB v3 [ 62481 ] | MariaDB v4 [ 148218 ] |
5.5 revno 4278:
102 rows in set (7 min 45.45 sec)
| 1 | SIMPLE | main_table | ALL | IDX_CATALOG_CATEGORY_FLAT_STORE_1_PATH | NULL | NULL | NULL | 143 | 98.60 | Using where; Using filesort |
| 1 | SIMPLE | url_rewrite | range | IDX_CORE_URL_REWRITE_TARGET_PATH_STORE_ID,IDX_CORE_URL_REWRITE_ID_PATH,IDX_CORE_URL_REWRITE_STORE_ID,FK_CORE_URL_REWRITE_CTGR_ID_CAT_CTGR_ENTT_ENTT_ID | IDX_CORE_URL_REWRITE_ID_PATH | 768 | NULL | 1138 | 75.04 | Range checked for each record (index map: 0x1E) |
select 1 AS `1` from `test`.`catalog_category_flat_store_1` `main_table` left join `test`.`core_url_rewrite` `url_rewrite` on(((`test`.`url_rewrite`.`category_id` = `test`.`main_table`.`entity_id`) and (`test`.`url_rewrite`.`is_system` = 1) and (`test`.`url_rewrite`.`store_id` = 1) and (`test`.`url_rewrite`.`id_path` like 'category/%'))) where ((`test`.`main_table`.`include_in_menu` = '1') and (`test`.`main_table`.`is_active` = '1') and (`test`.`main_table`.`path` like '1/2/%')) order by `test`.`main_table`.`position`
10.0 revno 4393:
102 rows in set (10 min 16.73 sec)
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+------+-------------+-------------+------+--------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------+---------+------+---------+----------+-------------------------------------------------+
| 1 | SIMPLE | main_table | ALL | IDX_CATALOG_CATEGORY_FLAT_STORE_1_PATH | NULL | NULL | NULL | 143 | 98.60 | Using where; Using filesort |
| 1 | SIMPLE | url_rewrite | ALL | IDX_CORE_URL_REWRITE_TARGET_PATH_STORE_ID,IDX_CORE_URL_REWRITE_ID_PATH,IDX_CORE_URL_REWRITE_STORE_ID,FK_CORE_URL_REWRITE_CTGR_ID_CAT_CTGR_ENTT_ENTT_ID | IDX_CORE_URL_REWRITE_ID_PATH | 768 | NULL | 1069786 | 0.08 | Range checked for each record (index map: 0x1E) |
Note | 1003 | select 1 AS `1` from `test`.`catalog_category_flat_store_1` `main_table` left join `test`.`core_url_rewrite` `url_rewrite` on(((`test`.`url_rewrite`.`category_id` = `test`.`main_table`.`entity_id`) and (`test`.`url_rewrite`.`is_system` = 1) and (`test`.`url_rewrite`.`store_id` = 1) and (`test`.`url_rewrite`.`id_path` like 'category/%'))) where ((`test`.`main_table`.`include_in_menu` = '1') and (`test`.`main_table`.`is_active` = '1') and (`test`.`main_table`.`path` like '1/2/%')) order by `test`.`main_table`.`position`
5.6 revno 6060:
102 rows in set (0.13 sec)
| 1 | SIMPLE | main_table | ALL | IDX_CATALOG_CATEGORY_FLAT_STORE_1_PATH | NULL | NULL | NULL | 143 | 98.60 | Using where; Using temporary; Using filesort |
| 1 | SIMPLE | url_rewrite | range | IDX_CORE_URL_REWRITE_TARGET_PATH_STORE_ID,IDX_CORE_URL_REWRITE_ID_PATH,IDX_CORE_URL_REWRITE_STORE_ID,FK_CORE_URL_REWRITE_CTGR_ID_CAT_CTGR_ENTT_ENTT_ID | IDX_CORE_URL_REWRITE_ID_PATH | 768 | NULL | 1138 | 100.00 | Using where; Using join buffer (Block Nested Loop) |
/* select#1 */ select 1 AS `1` from `test`.`catalog_category_flat_store_1` `main_table` left join `test`.`core_url_rewrite` `url_rewrite` on(((`test`.`url_rewrite`.`store_id` = 1) and (`test`.`url_rewrite`.`is_system` = 1) and (`test`.`url_rewrite`.`category_id` = `test`.`main_table`.`entity_id`) and (`test`.`url_rewrite`.`id_path` like 'category/%'))) where ((`test`.`main_table`.`include_in_menu` = '1') and (`test`.`main_table`.`is_active` = '1') and (`test`.`main_table`.`path` like '1/2/%')) order by `test`.`main_table`.`position`