Optimizations for derived tables in MySQL 5.6 and MariaDB 5._MySQL

php中文网
发布: 2016-05-31 08:49:54
原创
1109人浏览过

MariaDB

i had been involved with subquery optimizations fairly closely, but last week i was surprised to find out that mysql 5.6 does not supportderived table merging. this feature was among the subquery features in the abandoned mysql 6.0. in mariadb, it was finished and released as part ofmariadb 5.3/5.5. as for mysql, neither mysql 5.6, nor mysql 5.7 has this feature.

So what is this “derived merge”? It’s simple to understand. When one writes complex queries, it is common to use FROM-clause subqueries as a way to structure the query:

<font color="darkblue">select</font>sum(o_totalprice)<font color="darkblue">from</font>(<font color="darkblue">select</font> * <font color="darkblue">from</font> orders <font color="darkblue">where</font> o_orderpriority=’1-URGENT’) <font color="darkblue">as</font> high_prio_orders<font color="darkblue">where</font>o_orderdate <font color="darkblue">between</font> ‘1995-01-01′ <font color="darkblue">and</font> ‘1995-01-07′
登录后复制

MySQL optimizer processes this syntax very poorly. The basic problem is thatFROM-subqueries are always materialized exactly as-specified. Conditions from outside the subquery are applied only after the materialization.

In our example, tableordershas an index ono_orderdate, and there is a highly selective conditiono_orderdate BETWEEN ...which one can use for reading through the index. But the condition is located outside the subquery, so it will not be used when reading the table. Instead, we will get the following plan:

+----+-------------+------------+------+---------------+------+---------+------+---------+-------------+| id | select_type | table| type | possible_keys | key| key_len | ref| rows| Extra |+----+-------------+------------+------+---------------+------+---------+------+---------+-------------+|1 | PRIMARY | <derived2> | ALL| NULL| NULL | NULL| NULL | 1505799 | Using where ||2 | DERIVED | orders | ALL| NULL| NULL | NULL| NULL | 1505799 | Using where |+----+-------------+------------+------+---------------+------+---------+------+---------+-------------+
登录后复制

The meaning of it is:

  1. Do a full table scan is on table `orders`. We expect to read 1.5M rows. Write rows that matcho_orderpriority='1-URGENT'into a temporary table
  2. Read the temporary table back. Filter rows that matcho_orderdate between ...and compute the query result

MySQL 5.6 has added some improvements to this (link to the manual). They are:

  • The temporary table is materialized as late as possible. This has no effect of the speed of our example query, but it may have an effect for more complex queries.
    • EXPLAIN also will not materialize the temporary table
  • The optimizer has an option to create and use an index on the temporary table.

However, the base problem of materializing FROM subquery before applying any other optimization still remains.

In MariaDB, EXPLAIN will be different:

+------+-------------+--------+-------+---------------+---------------+---------+------+------+------------------------------------+| id | select_type | table| type| possible_keys | key | key_len | ref| rows | Extra|+------+-------------+--------+-------+---------------+---------------+---------+------+------+------------------------------------+|1 | SIMPLE| orders | range | i_o_orderdate | i_o_orderdate | 4 | NULL | 4358 | Using index condition; Using where |+------+-------------+--------+-------+---------------+---------------+---------+------+------+------------------------------------+
登录后复制

Note that we see only one line, and the table orders is accessed through an index ono_orderdate. RunningEXPLAIN EXTENDEDwill show why:


Message: select sum(`dbt3sf1`.`orders`.`o_totalprice`) AS `sum(o_totalprice)` from `dbt3sf1`.`orders` where ((`dbt3sf1`.`orders`.`o_orderpriority` = ‘1-URGENT’) and (`dbt3sf1`.`orders`.`o_orderDATE` between ‘1995-01-01′ and ‘1995-01-07′))

There is no FROM-clause subquery anymore. It has been merged into the upper select. This allowed the optimizer to avoid doing materialization, and also to use the condition and index ono_orderdateto construct arangeaccess.

Query execution time for this particular example went down from 15 sec to 0.25 sec, but generally, the difference can be as big as your table is big.

Posted inhow-it-works,mysql,mariadbon June 30th, 2014 by spetrunia| |

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号