29
www.2345.com MySQL 级优化之—— 查询逻辑及where条件提取 上海二三四五网络科技股份有限公司 联网研发中心 王德玖 2013-09-27

Mysql 高级优化之 逻辑处理

Embed Size (px)

Citation preview

Page 1: Mysql 高级优化之 逻辑处理

www.2345.com

MySQL 高级优化之——

查询逻辑及where条件提取

上海二三四五网络科技股份有限公司

互联网研发中心

王德玖

2013-09-27

Page 2: Mysql 高级优化之 逻辑处理

www.2345.com

议程

• Mysql 查询逻辑处理步骤

• 查询语句中where 条件如果提取

• 总结

• 问答

Page 3: Mysql 高级优化之 逻辑处理

www.2345.com

SELECT查询预览

SELECT DISTINCT <select_list>

FROM <left_table>

<join_type> JOIN <right_table>

ON <join_condition>

WHERE <where_condition>

GROUP BY <group_by_list>

WITH{CUBE|ROLLUP}

HAVING <having_condition>

ORDER BY <order_by_list>

LIMIT <limit_number>

Page 4: Mysql 高级优化之 逻辑处理

www.2345.com

SELECT 逻辑处理概览:

(8) SELECT (9) DISTINCT <select_list>

(1) FROM <left_table>

(3 ) <join_type> JOIN <right_table>

(2) ON <join_condition>

(4) WHERE <where_condition>

(5) GROUP BY <group_by_list>

(6) WITH{CUBE|ROLLUP}

(7) HAVING <having_condition>

(10) ORDER BY <order_by_list>

(11) LIMIT <limit_number>

11个步骤,最先执行

的是FROM操作,最后执行的是LIMIT操作。每个操作都会产

生一张虚拟表,以下记为“VTn”该虚拟表

作为一个处理的输入

Page 5: Mysql 高级优化之 逻辑处理

www.2345.com

第一组FROM、ON:

(8) SELECT (9) DISTINCT <select_list>

(1) FROM <left_table>

(3 ) <join_type> JOIN <right_table>

(2) ON <join_condition>

(4) WHERE <where_condition>

(5) GROUP BY <group_by_list>

(6) WITH{CUBE|ROLLUP}

(7) HAVING <having_condition>

(10) ORDER BY < order_by_list >

(11) LIMIT <limit_number>

对FROM子句中的左表<left_table>和右表

<right_table>执行笛卡儿

积(Cartesian product),产生虚拟表VT1

对虚拟表VT1应用ON筛选,

只有符合<join_condition>的行才被插入虚拟表VT2中

Page 6: Mysql 高级优化之 逻辑处理

www.2345.com

承前启后的join:

(8) SELECT (9) DISTINCT <select_list>

(1) FROM <left_table>

(3 ) <join_type> JOIN <right_table>

(2) ON <join_condition>

(4) WHERE <where_condition>

(5) GROUP BY <group_by_list>

(6) WITH{CUBE|ROLLUP}

(7) HAVING <having_condition>

(10) ORDER BY < order_by_list >

(11) LIMIT <limit_number>

如果指定了OUTER JOIN(如LEFT OUTER JOIN、

RIGHT OUTER JOIN),那么保留表中未匹配的行作为

外部行添加到虚拟表VT2中,产生虚拟表VT3。如果

FROM子句包含两个以上表,则对上一个连接生成的结果

表VT3和下一个表重复执行

步骤1)~步骤3),直到处理完所有的表为止。

Page 7: Mysql 高级优化之 逻辑处理

www.2345.com

Where你需要什么:

(8) SELECT (9) DISTINCT <select_list>

(1) FROM <left_table>

(3 ) <join_type> JOIN <right_table>

(2) ON <join_condition>

(4) WHERE <where_condition>

(5) GROUP BY <group_by_list>

(6) WITH{CUBE|ROLLUP}

(7) HAVING <having_condition>

(10) ORDER BY <having_condition>

(11) LIMIT <limit_number>

对虚拟表VT3应用

WHERE过滤条件,只有

符合<where_condition>的记录才被插入虚拟表

VT4中

Page 8: Mysql 高级优化之 逻辑处理

www.2345.com

GROUP BY:

(8) SELECT (9) DISTINCT <select_list>

(1) FROM <left_table>

(3 ) <join_type> JOIN <right_table>

(2) ON <join_condition>

(4) WHERE <where_condition>

(5) GROUP BY <group_by_list>

(6) WITH{CUBE|ROLLUP}

(7) HAVING <having_condition>

(10) ORDER BY < order_by_list >

(11) LIMIT <limit_number>

根据GROUP BY子句中的列,对VT4中的记录

进行分组操作,产生

VT5

如果有对表VT5进行CUBE或

ROLLUP操作,产生表VT6

Page 9: Mysql 高级优化之 逻辑处理

www.2345.com

组内过滤HAVING:

(8) SELECT (9) DISTINCT <select_list>

(1) FROM <left_table>

(3 ) <join_type> JOIN <right_table>

(2) ON <join_condition>

(4) WHERE <where_condition>

(5) GROUP BY <group_by_list>

(6) WITH{CUBE|ROLLUP}

(7) HAVING <having_condition>

(10) ORDER BY < order_by_list >

(11) LIMIT <limit_number>

对虚拟表VT6应

用HAVING过滤器,只

有符合<having_condition>的记录才被插入虚拟

表VT7中

Page 10: Mysql 高级优化之 逻辑处理

www.2345.com

选择去重:

(8) SELECT (9) DISTINCT <select_list>

(1) FROM <left_table>

(3 ) <join_type> JOIN <right_table>

(2) ON <join_condition>

(4) WHERE <where_condition>

(5) GROUP BY <group_by_list>

(6) WITH{CUBE|ROLLUP}

(7) HAVING <having_condition>

(10) ORDER BY <having_condition>

(11) LIMIT <limit_number>

把重复的行从VT8中删除,插

入VT9

执行SELECT操作,选择指定的列,插

入到虚拟表VT8中

Page 11: Mysql 高级优化之 逻辑处理

www.2345.com

排序,返回结果:

(8) SELECT (9) DISTINCT <select_list>

(1) FROM <left_table>

(3 ) <join_type> JOIN <right_table>

(2) ON <join_condition>

(4) WHERE <where_condition>

(5) GROUP BY <group _by_list>

(6) WITH{CUBE|ROLLUP}

(7) HAVING <having_condition>

(10) ORDER BY <having_condition>

(11) LIMIT <limit_number>

将虚拟表VT9中的记录

按照<order_by_list>进

行排序操作,产生虚拟

表VT10

取出指定行的记录,

产生虚拟表VT11,并返回给查询用户

Page 12: Mysql 高级优化之 逻辑处理

www.2345.com

查询总结…

(8) SELECT (9) DISTINCT <select_list>

(1) FROM <left_table>

(3 ) <join_type> JOIN <right_table>

(2) ON <join_condition>

(4) WHERE <where_condition>

(5) GROUP BY <group_by_list>

(6) WITH{CUBE|ROLLUP}

(7) HAVING <having_condition>

(10) ORDER BY < order_by_list >

(11) LIMIT <limit_number>

Join表生成笛卡尔积vt1

On条件过滤vt1插入到vt2

join未匹配的外部行插入得vt3

Where过滤vt3得vt4

分组vt4得出vt5

Page 13: Mysql 高级优化之 逻辑处理

www.2345.com

…查询总结

(8) SELECT (9) DISTINCT <select_list>

(1) FROM <left_table>

(3 ) <join_type> JOIN <right_table>

(2) ON <join_condition>

(4) WHERE <where_condition>

(5) GROUP BY <group_by_list>

(6) WITH{CUBE|ROLLUP}

(7) HAVING <having_condition>

(10) ORDER BY < order_by_list >

(11) LIMIT <limit_number>

Vt7排序后插入vt8

从vt8选择所需列得vt9有distinct删除重复行插入vt10

取出vt10指定行插入vt11并返回给用户

Having条件对vt6过滤得vt7

rollup对vt5汇总得vt6(CUBE mysql 还未实现)

Page 14: Mysql 高级优化之 逻辑处理

www.2345.com

Where中的查询条件提取…

表索引

数据

聚簇索引表 堆表

数据库数据的组成

表结构

Page 15: Mysql 高级优化之 逻辑处理

www.2345.com

Where中的查询条件提取…

堆表:所有的记录无序存储;

聚簇索引表:所有的记录按照记录主键进

行排序存储

表结构 表索引

Myisam .MYI innodb

in tablespace

.frm

数据元素

Page 16: Mysql 高级优化之 逻辑处理

www.2345.com

Where中的查询条件提取…

root@ test >show create table test\GTable: testCreate Table: CREATE TABLE `test` (`a` int(11) NOT NULL,`b` int(11) DEFAULT NULL,`c` int(11) DEFAULT NULL,`d` int(11) DEFAULT NULL,`e` varchar(10) DEFAULT NULL,PRIMARY KEY (`a`),KEY `idx_b_c_d` (`b`,`c`,`d`)

) ENGINE=MyISAM DEFAULT CHARSET=gbk

实例一创建表

这里是myisam表,即堆表

Page 17: Mysql 高级优化之 逻辑处理

www.2345.com

Where中的查询条件提取…

实例一插入数据

root@localhost: test >insert into test select 4,3,1,1,'d';root@localhost: test >insert into test select 1,1,1,1,'a'; root@localhost: test >insert into test select 9,9,9,9,'t'; root@localhost: test >insert into test select 2,2,2,2,'b'; root@localhost: test >insert into test select 5,2,3,5,'e'; root@localhost: test >insert into test select 3,3,2,2,'v'; root@localhost: test >insert into test select 7,4,5,5,'g'; root@localhost: test >insert into test select 6,6,4,4,'f';

Page 18: Mysql 高级优化之 逻辑处理

www.2345.com

Where中的查询条件提取…

索引组织,存储结构 311

999

4311d

1111a

9999t

2222b

5235e

3322v

7455g

6644f

堆表

索引:idx_b_c_d

图一

Page 19: Mysql 高级优化之 逻辑处理

www.2345.com

Where中的查询条件提取…

SQL的where条件提取

select * from test where b >= 2 and b < 9 and c > 1 and d != 4 and e != 'a';

结合图一索引思考此查询语句:where条件使用到了[b,c,d,e]四个字段,而test表的idx_b_c_d索引,恰好使用

了[b,c,d]这三个字段,

那么走idx_b_c_d索引进行条件过滤成为可能

Page 20: Mysql 高级优化之 逻辑处理

www.2345.com

Where中的查询条件提取…

索引范围检查

select * from test where b >= 2 and b < 9 and c > 1 and d != 4 and e != 'a';

起始范围:记录[2,2,2]是第一个需要检查的索引项。索引起始查

找范围由b >= 2,c > 1决定。

终止范围:记录[9,9,9]是第一个不需要检查的记录,而之前的记

录均需要判断。索引的终止查找

范围由b < 9决定;

Page 21: Mysql 高级优化之 逻辑处理

www.2345.com

Where中的查询条件提取…

索引范围检查

select * from test where b >= 2 and b < 9 and c > 1 and d != 4 and e != 'a';

固定了索引的查询范围

[(2,2,2),(9,9,9))之后,此索引范围中

并不是每条记录都是满足where查询

条件,例如:(3,1,1)不满足c > 1,(6,4,4)不满足d != 4的约束。而c,d列,均可在索引idx_b_c_d中过滤掉不

满足条件的索引记录。

因此,SQL中还可以使用c > 1 and d != 4条件进行索引记录的过滤

Page 22: Mysql 高级优化之 逻辑处理

www.2345.com

Where中的查询条件提取…

索引范围外检查

select * from test where b >= 2 and b < 9 and c > 1 and d != 4 and e != 'a';

可见,e != ‘a’这个查询条件,无法

在索引idx_a_b_c上进行过滤,因

为索引不包含e列,e列只在堆表上存在,

为了过滤此查询条件,必须将已

经满足索引查询条件的记录回表,

取出表中的e列,然后使用e列的查询条件e != ‘a’进行最终的过滤

4311d

1111a

9999t

2222b

5235e

3322v

7455g

6644f

堆表

Page 23: Mysql 高级优化之 逻辑处理

www.2345.com

Where中的查询条件提取…

where

Table FilterIndex FilterIndex Key

First Key Last Key

SQL的where条件,可归纳为3大类

Page 24: Mysql 高级优化之 逻辑处理

www.2345.com

Where中的查询条件提取…

释义过滤表 index key

Index Key

First Key

Last Key

查询确定

SQL查询

在索引中的连续范

围(起始范围+结束

范围)的条件

确定索引查

询的终止范围

确定索引查

询的起始范

Page 25: Mysql 高级优化之 逻辑处理

www.2345.com

Where中的查询条件提取…

Table Filter

Index Filter

索引过滤器及表过滤器

过滤索引查询范围中不

满足查询条件的记录

最后一道where条件的防线,

用于过滤通过前面索引考验的记录,此时的记录已

经满足了Index First Key与Index Last Key构成的范围,

并且满足Index Filter的条件

where

Index Key

Page 26: Mysql 高级优化之 逻辑处理

www.2345.com

Where中的查询条件提取…

Where提取的逻辑处理过程

First Key

Last Key

确定起终点

Index Filter

去除不符合规则记

Table Filter

过滤

返回

Page 27: Mysql 高级优化之 逻辑处理

www.2345.com

Where中的查询条件提取…

Mysql 5.6 特性:index condition pushdown

MySQL 5.6之前,不区分Index Filter与Table Filter,统统将Index First Key与Index Last Key范围内的索引记录回表读取完整记录,

然后返回给MySQL Server层进行过滤。而在MySQL 5.6之后,Index Filter与Table Filter分离,Index Filter下降到InnoDB的索引层面进行过滤,

减少了回表与返回MySQL Server层的记录交互开销,提高了SQL的执行

效率

Page 28: Mysql 高级优化之 逻辑处理

www.2345.com

结束

Q&A

Page 29: Mysql 高级优化之 逻辑处理

www.2345.com

谢谢