MySQL--视图优化(三)

续:

MySQL--视图优化(一)

MySQL--视图优化(二)


 

2 V5.7.5 视图和FROM子句中的派生表的重构

 

相关工作参见:http://dev.mysql.com/worklog/task/?id=5275

 

2.1.1 V5.7.5 视图和FROM子句中的派生表的重构内容

最近几年,MySQL的优化器进步很快,MySQL的Optimizer团队对于优化器作了许多的优化工作。

MySQL在5.7.5版本中,对于视图和FROM子句中的DERIVED table进行了一次重构工作,工作的结果:

1)从概念、编码实现的角度,统一了二者的处理方式,使得相似的内容处理(视图和派生表的处理方式)逻辑保持了一致,同一套代码清晰便于理解

2)提高了FROM子句中派生表的处理效率(对于可以merge的视图和派生表采用merge优化)

3)对于不可merge的视图和派生表采用“物化”的方式进行优化,达到只执行一次多次使用的优化目的

 

例如:

mysql> EXPLAIN SELECT * FROM t1, (SELECT * FROM t2) as tt;

+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+--------------------------------------+

| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra                                |

+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+--------------------------------------+

|  1 | SIMPLE      | t1    | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    3 |   100.00 | NULL                                 |

|  1 | SIMPLE      | t2    | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    4 |   100.00 | Using join buffer (Block Nested Loop)|

+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+--------------------------------------+

2 rows in set, 1 warning (0.00 sec)

 

从这个例子中可以看到,5.7.5版本中对于派生表采用了merge优化,消除了5.5中的子查询。这样查询效率得到较大提高。

 

从编码首先看,5.5代码mysql_make_view()中合并(merge)优化的代码被取出,这样就消除了单独优化视图的可能。

在sql_resolve.cc文件中通过调用SELECT_LEX::resolve_derived()统一对视图和派生表进行了如下操作:

 

for (TABLE_LIST *tl= get_table_list(); tl; tl= tl->next_local)

  对每个tl且是“视图或派生表”执行TABLE_LIST::resolve_derived();

for (TABLE_LIST *tl= get_table_list(); tl; tl= tl->next_local)

  对每个可merge的tl且是“视图或派生表”执行“合并”操作;

for (TABLE_LIST *tl= get_table_list(); tl; tl= tl->next_local)

  对每个不可merge的tl且是“视图或派生表”执行“物化”操作;

其中,tl可以是视图或派生表,这样的对象,要么被采用“合并”的方式优化,要么被采用“物化”的方式优化。

 

如下是一个物化的例子(派生表中多了一个LIMIT子句)。

mysql> EXPLAIN SELECT * FROM t1, (SELECT * FROM t2 LIMIT 1) as tt;

+----+-------------+------------+------------+--------+---------------+------+---------+------+------+----------+-------+

| id | select_type | table      | partitions | type   | possible_keys | key  | key_len | ref  | rows | filtered | Extra |

+----+-------------+------------+------------+--------+---------------+------+---------+------+------+----------+-------+

|  1 | PRIMARY     | <derived2> | NULL       | system | NULL          | NULL | NULL    | NULL |    1 |   100.00 | NULL  |

|  1 | PRIMARY     | t1         | NULL       | ALL    | NULL          | NULL | NULL    | NULL |    3 |   100.00 | NULL  |

|  2 | DERIVED     | t2         | NULL       | ALL    | NULL          | NULL | NULL    | NULL |    4 |   100.00 | NULL  |

+----+-------------+------------+------------+--------+---------------+------+---------+------+------+----------+-------+

3 rows in set, 1 warning (0.00 sec)

 

其实,MySQL优化器的进化一直在进行着,有些进步尽管不如5.7.5对派生表和视图的优化进步大,但每一个版本,总是在向前迈进。如5.6.3,物化操作只发生在执行阶段,如果是EXPLAIN获得执行计划,则物化操作不发生。

Materialization of subqueries in the FROM clause is postponed until their contents are needed during query execution, which improves performance。

 

2.1.2 V5.7.5 视图和FROM子句中的派生表的重构的限制

不是所有的视图和派生表都可以被merge,不可merge的情况,类似1.4节,即简单视图或派生表,可以被merge,复杂视图和带有GROUP/HAVING/DISTINCT/LIMIT/聚集函数等子句的派生表只能被物化。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值