Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2802707
  • 博文数量: 389
  • 博客积分: 4177
  • 博客等级: 上校
  • 技术积分: 4773
  • 用 户 组: 普通用户
  • 注册时间: 2008-11-16 23:29
文章分类

全部博文(389)

分类: Mysql/postgreSQL

2015-03-08 16:50:07

                        Mysql谓词下推技术

     上次和一个朋友在讨论一个Mysql连接的优化,他的观点是有对于
where条件的限制的表,可以先对这个表写一个from视图,在视图中先
用where条件做限制,然后再来做连接

原始语句是这样的

select *
from sbtest t1 join snapshot t2 on t1.id=t2.id
where  t2.snap_id=1420637262


改成如下的形式

select *
from sbtest t1 join (select * from  snapshot where snap_id=1420637262) t2
on t1.id=t2.id

这种观点主要是思想是对于有where条件限制的表,先尽量做限制。但是这种方式真的会执行率高吗? 我们首先来看看执行计划

mysql> explain
    -> select *
    -> from sbtest t1 join (select * from  snapshot where snap_id=1420637262) t2
    -> on t1.id=t2.id;
+----+-------------+------------+--------+---------------+---------+---------+-------+------+-------------+
| id | select_type | table      | type   | possible_keys | key     | key_len | ref   | rows | Extra       |
+----+-------------+------------+--------+---------------+---------+---------+-------+------+-------------+
|  1 | PRIMARY     | | ALL    | NULL          | NULL    | NULL    | NULL  | 5846 | NULL        |
|  1 | PRIMARY     | t1         | eq_ref | PRIMARY       | PRIMARY | 4       | t2.id |    1 | Using where |
|  2 | DERIVED     | snapshot   | ALL    | NULL          | NULL    | NULL    | NULL  | 5846 | Using where |
+----+-------------+------------+--------+---------------+---------+---------+-------+------+-------------+
3 rows in set (0.00 sec)

首先看id为2的,对子查询做一个全表扫描,然后使用where条件过滤.结果再驱动到id为1,然后再和t1表做一个连接,这样看起来是先把t2中不符合where条件元组过滤掉了,好像是目的也已经达到了.


再来看看原始语句的执行计划

mysql> explain
    -> select *
    -> from sbtest t1 join snapshot t2 on t1.id=t2.id
    -> where  t2.snap_id=1420637262;
+----+-------------+-------+--------+---------------+---------+---------+-----------+------+-------------+
| id | select_type | table | type   | possible_keys | key     | key_len | ref       | rows | Extra       |
+----+-------------+-------+--------+---------------+---------+---------+-----------+------+-------------+
|  1 | SIMPLE      | t2    | ALL    | PRIMARY       | NULL    | NULL    | NULL      | 5846 | Using where |
|  1 | SIMPLE      | t1    | eq_ref | PRIMARY       | PRIMARY | 4       | db1.t2.id |    1 | Using where |
+----+-------------+-------+--------+---------------+---------+---------+-----------+------+-------------+
2 rows in set (0.00 sec)


在这里首先是对t2表进行全表扫描,但是where条件是在扫描t2的时候过滤还是连接过后过滤呢?通过执行计划我们可以很明显可以看出是后一种方式,在对t2表进行全表扫描后,使用where条件过滤,然后结果只有一行了,注意执行计划的第二行的 type=eq_ref,后面的rows为1 。

   我们这种方式叫作谓词下推技术,事实主流的数据库基本上都支持这种方式的优化。其原则是在一个查询树中,对于
任何选择都尽量早做选择,然后进行一步的处理.可见我们并不需要改写这个sql,优化器会自动去帮我们做这种优化.

 

 

阅读(6924) | 评论(1) | 转发(1) |
给主人留下些什么吧!~~

lyhabc2015-03-08 22:46:36

谓词下推很早就有了