[MDEV-579] LP:921773 - Suboptimal plan chosen for Q16 of a MyISAM DBT-3 database Created: 2012-01-25  Updated: 2023-12-20

Status: Stalled
Project: MariaDB Server
Component/s: None
Affects Version/s: 5.3.12
Fix Version/s: 5.5

Type: Bug Priority: Minor
Reporter: Igor Babaev Assignee: Igor Babaev
Resolution: Unresolved Votes: 0
Labels: Launchpad

Attachments: XML File LPexportBug921773.xml    
Issue Links:
Duplicate
duplicates MDEV-147 lp:921773 - Suboptimal plan chosen fo... Closed

 Description   

The optimizer of maridb-5.3 chooses a suboptimal execution plan for Q16 over MyISAM DBT-3 database of scale factor 10
if a join buffer is employed.

With the settings:

set tmp_table_size=1024*1024*64;
set max_heap_table_size=1024*1024*64;
set sort_buffer_size=1024*1024*64;
set optimizer_switch='semijoin=on';
set optimizer_switch='materialization=on';
set optimizer_switch='mrr=on';
set join_buffer_space_limit=1024*1024*128;
set join_buffer_size=1024*1024*32;
set optimizer_switch='mrr_sort_keys=on';
set join_cache_level=6;

the optimizer of 5.3 chooses the following execution plan:

MariaDB [dbt3x10_myisam_56]> explain
    -> select sql_calc_found_rows
    ->        p_brand, p_type, p_size, count(distinct ps_suppkey) as supplier_cnt
    -> from partsupp, part
    -> where p_partkey = ps_partkey and p_brand <> 'Brand#45'
    ->       and p_type not like 'MEDIUM POLISHED%'and p_size in
    ->       (49, 14, 23, 45, 19, 3, 36, 9)
    ->       and ps_suppkey not in (select s_suppkey from supplier
    ->                              where s_comment like '%Customer%Complaints%')
    -> group by p_brand, p_type, p_size
    -> order by supplier_cnt desc, p_brand, p_type, p_size
    -> limit 10;
+----+--------------+----------+--------+----------------------+---------+---------+---------------------------------------+---------+---------------------------------------------------------------------------------+
| id | select_type  | table    | type   | possible_keys        | key     | key_len | ref                                   | rows    | Extra                                                                           |
+----+--------------+----------+--------+----------------------+---------+---------+---------------------------------------+---------+---------------------------------------------------------------------------------+
|  1 | PRIMARY      | partsupp | index  | PRIMARY,i_ps_partkey | PRIMARY | 8       | NULL                                  | 8000000 | Using where; Using index; Using temporary; Using filesort                       |
|  1 | PRIMARY      | part     | eq_ref | PRIMARY              | PRIMARY | 4       | dbt3x10_myisam_56.partsupp.ps_partkey |       1 | Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan |
|  2 | MATERIALIZED | supplier | ALL    | PRIMARY              | NULL    | NULL    | NULL                                  |  100000 | Using where                                                                     |
+----+--------------+----------+--------+----------------------+---------+---------+---------------------------------------+---------+---------------------------------------------------------------------------------+

The execution by this plan on a cold server took me 1 min 29.81 sec.

However, when with the same settings the driving table is the table part and the execution plan is:

MariaDB [dbt3x10_myisam_56]> explain
    -> select sql_calc_found_rows
    ->        p_brand, p_type, p_size, count(distinct ps_suppkey) as supplier_cnt
    -> from partsupp, part use index()
    -> where p_partkey = ps_partkey and p_brand <> 'Brand#45'
    ->       and p_type not like 'MEDIUM POLISHED%'and p_size in
    ->       (49, 14, 23, 45, 19, 3, 36, 9)
    ->       and ps_suppkey not in (select s_suppkey from supplier
    ->                              where s_comment like '%Customer%Complaints%')
    -> group by p_brand, p_type, p_size
    -> order by supplier_cnt desc, p_brand, p_type, p_size
    -> limit 10;
+----+--------------+----------+------+----------------------+--------------+---------+----------------------------------+---------+----------------------------------------------+
| id | select_type  | table    | type | possible_keys        | key          | key_len | ref                              | rows    | Extra                                        |
+----+--------------+----------+------+----------------------+--------------+---------+----------------------------------+---------+----------------------------------------------+
|  1 | PRIMARY      | part     | ALL  | NULL                 | NULL         | NULL    | NULL                             | 2000000 | Using where; Using temporary; Using filesort |
|  1 | PRIMARY      | partsupp | ref  | PRIMARY,i_ps_partkey | i_ps_partkey | 4       | dbt3x10_myisam_56.part.p_partkey |       4 | Using where                                  |
|  2 | MATERIALIZED | supplier | ALL  | PRIMARY              | NULL         | NULL    | NULL                             |  100000 | Using where                                  |
+----+--------------+----------+------+----------------------+--------------+---------+----------------------------------+---------+----------------------------------------------+

an execution of the query takes significantly less time.
The execution by this plan on a cold server took me 38.42 sec .

A similar performance difference can be observed if to set the materialization flag of the optimizer switch to 'off'.

The execution by the plan:

MariaDB [dbt3x10_myisam_56]> explain
    -> select sql_calc_found_rows
    ->        p_brand, p_type, p_size, count(distinct ps_suppkey) as supplier_cnt
    -> from partsupp, part
    -> where p_partkey = ps_partkey and p_brand <> 'Brand#45'
    ->       and p_type not like 'MEDIUM POLISHED%'and p_size in
    ->       (49, 14, 23, 45, 19, 3, 36, 9)
    ->       and ps_suppkey not in (select s_suppkey from supplier
    ->                              where s_comment like '%Customer%Complaints%')
    -> group by p_brand, p_type, p_size
    -> order by supplier_cnt desc, p_brand, p_type, p_size
    -> limit 10;
+----+--------------------+----------+-----------------+----------------------+---------+---------+---------------------------------------+---------+---------------------------------------------------------------------------------+
| id | select_type        | table    | type            | possible_keys        | key     | key_len | ref                                   | rows    | Extra                                                                           |
+----+--------------------+----------+-----------------+----------------------+---------+---------+---------------------------------------+---------+---------------------------------------------------------------------------------+
|  1 | PRIMARY            | partsupp | index           | PRIMARY,i_ps_partkey | PRIMARY | 8       | NULL                                  | 8000000 | Using where; Using index; Using temporary; Using filesort                       |
|  1 | PRIMARY            | part     | eq_ref          | PRIMARY              | PRIMARY | 4       | dbt3x10_myisam_56.partsupp.ps_partkey |       1 | Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan |
|  2 | DEPENDENT SUBQUERY | supplier | unique_subquery | PRIMARY              | PRIMARY | 4       | func                                  |       1 | Using where                                                                     |
+----+--------------------+----------+-----------------+----------------------+---------+---------+---------------------------------------+---------+---------------------------------------------------------------------------------+

took me 3 min 8.70 sec,
while the execution by this plan:

MariaDB [dbt3x10_myisam_56]> explain
    -> select sql_calc_found_rows
    ->        p_brand, p_type, p_size, count(distinct ps_suppkey) as supplier_cnt
    -> from partsupp, part use index()
    -> where p_partkey = ps_partkey and p_brand <> 'Brand#45'
    ->       and p_type not like 'MEDIUM POLISHED%'and p_size in
    ->       (49, 14, 23, 45, 19, 3, 36, 9)
    ->       and ps_suppkey not in (select s_suppkey from supplier
    ->                              where s_comment like '%Customer%Complaints%')
    -> group by p_brand, p_type, p_size
    -> order by supplier_cnt desc, p_brand, p_type, p_size
    -> limit 10;
+----+--------------------+----------+-----------------+----------------------+--------------+---------+----------------------------------+---------+---------------------------------------------------------------------------------+
| id | select_type        | table    | type            | possible_keys        | key          | key_len | ref                              | rows    | Extra                                                                           |
+----+--------------------+----------+-----------------+----------------------+--------------+---------+----------------------------------+---------+---------------------------------------------------------------------------------+
|  1 | PRIMARY            | part     | ALL             | NULL                 | NULL         | NULL    | NULL                             | 2000000 | Using where; Using temporary; Using filesort                                    |
|  1 | PRIMARY            | partsupp | ref             | PRIMARY,i_ps_partkey | i_ps_partkey | 4       | dbt3x10_myisam_56.part.p_partkey |       4 | Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan |
|  2 | DEPENDENT SUBQUERY | supplier | unique_subquery | PRIMARY              | PRIMARY      | 4       | func                             |       1 | Using where                                                                     |
+----+--------------------+----------+-----------------+----------------------+--------------+---------+----------------------------------+---------+---------------------------------------------------------------------------------+

took me 50.25 sec.

The current mysql 5.6 does not support materialization of subqueries, but it chooses the faster plan with the table part as the driving table.



 Comments   
Comment by Rasmus Johansson (Inactive) [ 2012-03-20 ]

Launchpad bug id: 921773

Comment by Julien Fritsch [ 2023-12-05 ]

Automated message:
----------------------------
Since this issue has not been updated since 6 weeks, it's time to move it back to Stalled.

Generated at Thu Feb 08 06:29:48 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.