最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
当前位置: 首页 - 科技 - 知识百科 - 正文

OptimizationsforderivedtablesinMySQL5.6andMariaDB5._MySQL

来源:动视网 责编:小采 时间:2020-11-09 19:59:12
文档

OptimizationsforderivedtablesinMySQL5.6andMariaDB5._MySQL

OptimizationsforderivedtablesinMySQL5.6andMariaDB5._MySQL: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
推荐度:
导读OptimizationsforderivedtablesinMySQL5.6andMariaDB5._MySQL: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


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:

selectsum(o_totalprice)from(select * from orders where o_orderpriority=’1-URGENT’) as high_prio_orderswhereo_orderdate between ‘1995-01-01′ and ‘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 |  | 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| |

    文档

    OptimizationsforderivedtablesinMySQL5.6andMariaDB5._MySQL

    OptimizationsforderivedtablesinMySQL5.6andMariaDB5._MySQL: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 and for
    • 热门焦点

    最新推荐

    猜你喜欢

    热门推荐

    专题
    Top