您的位置:首页 > 数据库 > MySQL

mysql表关联中的索引使用情况

2015-12-22 17:47 513 查看
2015-12-22 17:47
874人阅读 评论(0)
收藏
举报

本文章已收录于:



MySQL知识库



分类:
mysq优化(26)




作者同类文章X

版权声明:本文为博主原创文章,未经博主允许不得转载。

MySQL在某些情况下可以自动优化表关联的关联条件,如:通过分析条件中的字段是否有索引,关联表中的数据总数之类,通过这些条件mysql便可以实现一些自动优化sql语句的功能。

以下几种情况基本是靠一些简单实验进行验证,没有得到确切的官方文档证实

一、inner join情况下mysql自动优化

表结构细节不做介绍,简单介绍下

bus_creative表中的owner字段和sys_user表中的id字段在业务上是外键关联,n-->1,但是owner字段没有建立索引,业务上一般bus_creative数据量大于sys_user,这下就好玩了,先看下通过EXPLAIN执行后的结果

EXPLAIN select b.id from dshp.bus_creative a inner join dshp.sys_user b on a.`owner`=b.id;



下面是交换完关联条件位置后的结果

EXPLAIN select b.id from dshp.sys_user b join dshp.bus_creative a on b.id=a.`owner`;



这里多说一下EXPLAIN的id选项

id 列

建表:

create table a(a_id int);

create table b(b_id int);

create table c(c_id int);

mysql> explain select * from a join b on a_id=b_id where b_id in (select c_id from c);

+----+--------------------+-------+...

| id | select_type        | table |...

+----+--------------------+-------+...

|  1 | PRIMARY            | a     |...

|  1 | PRIMARY            | b     |...

|  2 | DEPENDENT SUBQUERY | c     |...

+----+--------------------+-------+...

从 3 个表中查询,对应输出 3 行,每行对应一个表, id 列表示执行顺序,id 越大,越先执行,id 相同,由上至下执行。此处的执行顺序为(以 table 列表示):c -> a -> b

从上面两个图中可以看到都是先执行的a表,再执行b表,这是为什么呢?啪啪的你知道吗?

来让哥给你解释下吧,此时mysql会先分析关联条件中的两个字段owner和id,mysql掐指一算id是主键,owner是普通字段没有索引,这就好办了,肯定是以有主键或者索引的表数据为查询基准数据,然后遍历没有索引字段的表数据,这样的结果就是先遍历a表,然后以a表的数据在b表中进行查询(因为b中的id是主键索引,查的快啊,如果顺序反过来你想想会是什么结果,肯定用不到索引,这样查询速度肯定慢!),而且图2证明交换关联条件的位置结果也是一样的,更加印证了上面的逻辑。

乖乖了,原来mysql这么智能啊!

废个话,要不你个屌丝都能搞个数据库系统了,还要人家mysql作甚。

。。。这只是毛毛雨啦

接下来看个更屌的

哥哥假想如果把关联条件中owner也做成索引,此时mysql他老人家该怎么玩呢,

走起来,哥先建个索引,索引名称是index_owner,这时我们不妨大胆猜测一下结果,

两个关键点,

1.a表中数据量10万,b表中数据量2千吧

2.a中owner是索引,b中id是主键

此时用你那大腿猜猜都该猜到,肯定是先执行数据量少而且关联字段中对方表字段又是索引的那个啊


然后再看看实验结果吧,上图

EXPLAIN select b.id from dshp.bus_creative a join dshp.sys_user b on a.`owner`=b.id;



看看吧,mysql他老人家也是这么想的

,而且该用到的索引也都用到了

二、left/right outer join情况下指定顺序执行

基于上面的结果,如果指定了left/right ouert的话,不用想,此时肯定得以left/right指定的那个表为主表先查询,什么?要问我为什么,呵呵,天机不可泄露!我去,你丫滚犊子吧。。。。

因为如果指定了outer后不管怎么优化指定的表数据肯定是全部显示,所以肯定先执行了。

有图有真相就在这里晒:

EXPLAIN select b.id from dshp.bus_creative a
left join dshp.sys_user b on a.`owner`=b.id;



换个位置再来一次


EXPLAIN select b.id from dshp.bus_creative a right join dshp.sys_user b on a.`owner`=b.id;





顶 0 踩 0
 
 
上一篇Java中String、StringBuilder和StringBuffer的简单区别

下一篇mysql数据文件

我的同类文章

mysq优化(26)

http://blog.csdn.net
关于mysql 删除数据后物理空间未释放(转载)2016-03-07阅读68

mysql优化(1)show命令 慢查询日志 explain profiling2016-02-25阅读73

大数据下mysql配置2015-12-11阅读85

实例说明optimize table在优化mysql时很重要2015-11-27阅读44

高性能MySql进化论(十四):复制(Replication)2015-11-26阅读79

mysql优化(2)索引优化 配置优化2016-02-25阅读92

MySQL Profiling的使用2016-02-25阅读70

高性能MySQL读书笔记:找出谁持有锁2015-11-27阅读72

MySql索引算法原理解析(通俗易懂,只讲B-tree)2015-11-27阅读145

高性能MySql进化论(十三):查询缓存机制2015-11-26阅读86

更多文章
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: