<?xml version="1.0" encoding="utf-8"?>
<launchpad-bug id="921773">
  <date_last_updated>2012-03-20 15:37:55.907131+00:00</date_last_updated>
  <api_links>
    <bug_api_link>https://api.launchpad.net/1.0/bugs/921773</bug_api_link>
    <bug_owner_link>https://api.launchpad.net/1.0/~igorb-seattle</bug_owner_link>
    <milestone_link>https://api.launchpad.net/1.0/maria/+milestone/5.3</milestone_link>
    <linked_branches_collection_link>https://api.launchpad.net/1.0/bugs/921773/linked_branches</linked_branches_collection_link>
    <activity_link>https://api.launchpad.net/1.0/bugs/921773/activity</activity_link>
  </api_links>
  <bug_web_link>https://bugs.launchpad.net/bugs/921773</bug_web_link>
  <owner>Igor Babaev</owner>
  <assignee>Igor Babaev</assignee>
  <milestone_title>Maria 5.3</milestone_title>
  <duplicate_link></duplicate_link>
  <duplicate_bug_id></duplicate_bug_id>
  <title>Suboptimal plan chosen for Q16 of a MyISAM DBT-3 database</title>
  <status>In Progress</status>
  <importance>Low</importance>
  <created>2012-01-25 19:39:03.874976+00:00</created>
  <description>
<![CDATA[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.]]>  </description>
  <activities>
    <activity datechanged="2012-01-25T19:39:03.874976+00:00">
      <oldvalue>
<![CDATA[]]>      </oldvalue>
      <newvalue>
<![CDATA[]]>      </newvalue>
      <whatchanged>bug</whatchanged>
      <person>Igor Babaev</person>
      <message>added bug</message>
    </activity>
    <activity datechanged="2012-01-25T19:39:22.096688+00:00">
      <oldvalue>
<![CDATA[New]]>      </oldvalue>
      <newvalue>
<![CDATA[Confirmed]]>      </newvalue>
      <whatchanged>maria: status</whatchanged>
      <person>Igor Babaev</person>
      <message></message>
    </activity>
    <activity datechanged="2012-01-25T19:39:59.811652+00:00">
      <oldvalue>
<![CDATA[Undecided]]>      </oldvalue>
      <newvalue>
<![CDATA[High]]>      </newvalue>
      <whatchanged>maria: importance</whatchanged>
      <person>Igor Babaev</person>
      <message></message>
    </activity>
    <activity datechanged="2012-01-25T19:40:06.163885+00:00">
      <oldvalue>
<![CDATA[]]>      </oldvalue>
      <newvalue>
<![CDATA[Igor Babaev (igorb-seattle)]]>      </newvalue>
      <whatchanged>maria: assignee</whatchanged>
      <person>Igor Babaev</person>
      <message></message>
    </activity>
    <activity datechanged="2012-01-25T19:40:10.840953+00:00">
      <oldvalue>
<![CDATA[]]>      </oldvalue>
      <newvalue>
<![CDATA[5.3]]>      </newvalue>
      <whatchanged>maria: milestone</whatchanged>
      <person>Igor Babaev</person>
      <message></message>
    </activity>
    <activity datechanged="2012-02-17T05:27:56.700887+00:00">
      <oldvalue>
<![CDATA[The optimizer of maridb-5.3 chooses a suboptimal execution plan for 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.]]>      </oldvalue>
      <newvalue>
<![CDATA[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.]]>      </newvalue>
      <whatchanged>description</whatchanged>
      <person>Igor Babaev</person>
      <message></message>
    </activity>
    <activity datechanged="2012-02-17T09:07:33.194103+00:00">
      <oldvalue>
<![CDATA[Confirmed]]>      </oldvalue>
      <newvalue>
<![CDATA[In Progress]]>      </newvalue>
      <whatchanged>maria: status</whatchanged>
      <person>Igor Babaev</person>
      <message></message>
    </activity>
    <activity datechanged="2012-03-20T15:37:54.554263+00:00">
      <oldvalue>
<![CDATA[High]]>      </oldvalue>
      <newvalue>
<![CDATA[Low]]>      </newvalue>
      <whatchanged>maria: importance</whatchanged>
      <person>Michael Widenius</person>
      <message></message>
    </activity>
  </activities>
  <comments>
    <comment commentlink="https://api.launchpad.net/1.0/maria/+bug/921773/comments/0" datecreated="2012-01-25T19:39:03.874976+00:00">
      <person>Igor Babaev</person>
      <subject>
<![CDATA[Suboptimal plan chosen for Q16 of a MyISAM DBT-3 database]]>      </subject>
      <content>
<![CDATA[The optimizer of maridb-5.3 chooses a suboptimal execution plan for 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.]]>      </content>
    </comment>
  </comments>
</launchpad-bug>
