stright 在mysql_MySQL优化的奇技淫巧之STRAIGHT_JOIN

最近没怎么搞SQL优化,碰巧数据库被慢查询搞挂了,于是拿来练练手。

问题

通过「SHOW FULL PROCESSLIST」语句很容易就能查到问题SQL,如下:

SELECT post.*

FROM post

INNER JOIN post_tag ON post.id = post_tag.post_id

WHERE post.status = 1 AND post_tag.tag_id = 123

ORDER BY post.created DESC

LIMIT 100

说明:因为post和tag是多对多的关系,所以存在一个关联表post_tag。

试着用EXPLAIN查询一下SQL执行计划(篇幅所限,结果有删减):

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

| table | key | rows | Extra |

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

| post_tag | tag_id | 71220 | Using where; Using filesort |

| post | PRIMARY | 1 | Using where |

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

下面给出优化后的SQL,唯一的变化就是把连接方式改成了「STRAIGHT_JOIN」:

SELECT post.*

FROM post

STRAIGHT_JOIN post_tag ON post.id = post_tag.post_id

WHERE post.status = 1 AND post_tag.tag_id = 123

ORDER BY post.created DESC

LIMIT 100

试着用EXPLAIN查询一下SQL执行计划(篇幅所限,结果有删减):

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

| table | key | rows | Extra |

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

| post | status_created | 119340 | Using where |

| post_tag | post_id | 1 | Using where |

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

对比优化前后两次EXPLAIN的结果来看,优化后的SQL虽然「rows」更大了,但是没有了「Using filesort」,综合来看,性能依然得到了提升。

提醒:注意两次EXPLAIN结果中各个表出现的先后顺序,稍后会解释。

解释

对第一条SQL而言,为什么MySQL优化器选择了一个耗时的执行方案?对第二条SQL而言,为什么把连接方式改成STRAIGHT_JOIN之后就提升了性能?

这一切还得从MySQL对多表连接的处理方式说起,首先MySQL优化器要确定以谁为驱动表,也就是说以哪个表为基准,在处理此类问题时,MySQL优化器采用了简单粗暴的解决方法:哪个表的结果集小,就以哪个表为驱动表,当然MySQL优化器实际的处理方式会复杂许多,具体可以参考:MySQL优化器如何选择索引和JOIN顺序。

说明:在EXPLAIN结果中,第一行出现的表就是驱动表。

继续post连接post_tag的例子,MySQL优化器有如下两个选择,分别是:

以post为驱动表,通过status_created索引过滤,结果集119340行

以post_tag为驱动表,通过tag_id索引过滤,结果集71220行

显而易见,post_tag过滤的结果集更小,所以MySQL优化器选择它作为驱动表,可悲催的是我们还需要以post表中的created字段来排序,也就是说排序字段不在驱动表里,于是乎不可避免的出现了「Using filesort」,甚至「Using temporary」。

知道了来龙去脉,优化起来就容易了,要尽可能的保证排序字段在驱动表中,所以必须以post为驱动表,于是乎必须借助「STRAIGHT_JOIN」强制连接顺序。

实际上在某些特殊情况里,排序字段可以不在驱动表里,比如驱动表结果集只有一行记录,并且在连接其它表时,索引除了连接字段,还包含了排序字段,此时连接表后,索引中的数据本身自然就是排好序的。

既然聊到这里顺带说点题外话,大家可能会遇到类似下面的问题:原本运行良好的查询语句,过了一段时间后,可能会突然变得很糟糕。一个很大可能的原因就是数据分布情况发生了变化,从而导致MySQL优化器对驱动表的选择发生了变化,进而出现索引失效的情况,所以没事最好多查查,关注一下这些情况。

对于「STRAIGHT_JOIN」,我总觉得这种非标准的语法属于奇技淫巧的范畴,能不用尽量不用,毕竟多数情况下,MySQL优化器都能做出正确的选择。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/244158.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

小说不“好看”,读者就给你“好看”

小说的病变和无可救药的衰竭是因为小说不好看 □主 持 人:兴 安 青年作家:丁 天 邱华栋 陆 涛 古清生 小说是什么?是“街谈巷议”———这是我们的老祖宗概括的,就是说它生于民间,是给更多的人看的&#x…

狗肉朋友

想想几年的圣诞聚会,朋友、哥们、同事、陌生人,每一年人走马灯似的变换,有的早在记忆中消失,如过眼烟云.而一直能保留下来的就那么几个朋友。 随着年龄的增长,自己在交往中纳新的能力和兴致越来越低,朋友的圈子越来越小,过去的那种结交天下豪杰的扩张心理没有了,守住故交,守住最…

mysql json坑_使用mysql innodb 使用5.7的json类型遇到的坑和解决办法

----------------------------------------------#查询JSON的某个字段select data -> ‘$.Host‘ from temp#创建虚拟列ALTER TABLE temp ADD host varchar(128) GENERATED ALWAYS AS (json_extract(data,‘$.Host‘)) VIRTUAL;#给虚拟列创建索引ALTER TABLE temp ADD INDEX…

恐怖小说之王——斯蒂芬·金 (转贴)

《宠物公墓》改编自斯蒂芬金的同名小说,在所有斯蒂芬金的恐怖小说里,恐怕就属这一部是最吓人的了。但斯蒂芬金的原著由于篇幅过长,难免有拖沓之感,当被改编成电影时,斯蒂芬金非常有效地压缩了与恐怖无关的枝节&#xf…

买了几张好碟

最喜欢的是《塔尔可夫斯基的全集》。以前有他零散的,几乎全了,可是看到整套的,包装又漂亮,声音又进化了5.1声道,确实没有理由不收啊。 《天下无贼》(正版),《狂蟒之灾2》…

mysql unix_timestamp 格式化_FROM_UNIXTIME 格式化MYSQL时间戳函数_MySQL

unix时间戳bitsCN.com函数:FROM_UNIXTIME作用:将MYSQL中以INT(11)存储的时间以”YYYY-MM-DD”格式来显示。语法:FROM_UNIXTIME(unix_timestamp,format)返回表示 Unix 时间标记的一个字符串,根据format字符串格式化。format可以包含…

酒喝高了,歌听多了

我常常忘记自己是蒙古人。昨天去了达尔汗蒙古风情餐吧,参加了蒙古的同乡会。AA制。好久没有参加这样的活动了,见到了些老面孔,大多是新面孔。有的胖了,有的老了,有的单身了,有的成双了,有的叫不…

抚摸斯蒂芬·金 (图)

<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" />最近翻到一本美国恐怖小说大师斯蒂芬金的自传《抚摸恐怖——我的创作生涯》&#xff0c;珠海出版社2002年5月出版。书中披露了斯蒂芬金很多不为人知的写作经历以及对恐怖小说的看…

mysql设置定位慢查询_mysql优化——定位慢查询

1.定位慢查询1、show status 命令命令使用方式&#xff1a;show [session|global] status like slow_queries如果你不写 [session|global] 默认是session 会话&#xff0c;指取出当前窗口的执行&#xff0c;如果你想看所有(从mysql 启动到现在&#xff0c;则应该 global)执行s…

当我们年轻的时候 (转贴)

当我们年轻的时候 徐坤/文 这是一张十年前的照片。1996 年底&#xff0c;《小说月报》第7届百花奖发奖会在天津蓟县举行。获奖作者与编辑一应到达。左起&#xff1a;徐坤&#xff0c;刘醒龙&#xff0c;毕飞宇&#xff0c;李师东&#xff0c;李敬泽&#xff0c;兴安。 时值隆…

python 对象的异或运算符_python的运算符

算数运算符算数运算符主要用作于计算机的算数运算种类符号作用加法、字符串的拼接-减法*乘法、字符串的重复/除法//地板除(除法)%取余(除法)**幂运算# 数字类型的加法运算print(1 1) # 2print(False 1) # 1print(0j 1) # (10j)# 字…

希望我不会“伤心至死”

刚收到鬼古女的最新小说《伤心至死——万劫》。这好象是他的第三部长篇&#xff0c;上海人民出版社出版2005年10月出版。也是他《伤心至死》悬疑系列的第一部。我和鬼古女只在网上有过交流&#xff0c;据说这是一对旅居美国的神秘夫妇的笔名。我喜欢他的小说&#xff0c;曾写过…

同盟与对抗:谈《少女杜拉的故事》中的治疗关系(转)

《少女杜拉的故事》是弗洛伊德众多精神分析实例报告中最具代表性的一例。它记叙了弗洛伊德对杜拉神经症的治疗过程&#xff0c;从中我们可以了解到弗洛伊德精神分析学说的理论及运用。杜拉是一个18岁的女孩&#xff0c;她由于反复咳嗽、声嘶、呼吸困难而来就诊&#xff0c;弗洛…

圣诞是我们这样过的,美女如云 (图)

圣诞是这样子过的&#xff0c;美女如云&#xff0c;只可惜靓崽忒少&#xff0c;唉&#xff0c;美女少了没劲&#xff0c;美女多了呢也麻烦&#xff0c;况且还有藏族美女给敬酒唱歌。地点是在中华民族园边上的茶马驿站&#xff0c;吃的是“马帮菜”&#xff0c;知道什么是“马帮…

java对象复制_Java对象的复制三种方式

Java对象的复制三种方式概述在实际编程过程中&#xff0c;我们常常要遇到这种情况&#xff1a;有一个对象A&#xff0c;在某一时刻A中已经包含了一些有效值&#xff0c;此时可能 会需要一个和A完全相同新对象B&#xff0c;并且此后对B任何改动都不会影响到A中的值&#xff0c;也…

新年快乐

同时两个朋友发来的&#xff0c;打开了还挺有意思。在新年到来的最后一天&#xff0c;收到这个小小的礼物还是很高兴&#xff0c;说明人家还记得你&#xff0c;常说君子之交淡如水&#xff0c;水其实我们不缺&#xff0c;我们往往缺的就是一句小小的问候&#xff0c;并且在一个…

看徐坤的话剧《性情男女》

昨晚应邀去看了徐坤的话剧《性情男女》&#xff0c;说实在话好的超乎了我的想象。这几年话剧多被国外经典剧目或者历史剧或者老剧目统治&#xff0c;现实题材的话剧少之又少&#xff0c;而我想看的更几乎为零。所以这个剧确实应该让我拍手。我们这些饱经沧桑的人、老油条或者麻…

java 字符串子串_java实现字符串匹配求两个字符串的最大公共子串

本文实例讲述了java实现求两个字符串最大公共子串的方法。分享给大家供大家参考&#xff0c;具体如下&#xff1a;最近在项目工作中有一个关于文本对比的需求&#xff0c;经过这段时间的学习&#xff0c;总结了这篇博客内容&#xff1a;求两个字符串的最大公共子串。算法思想&a…

读《伤心至死》兼谈恐怖悬疑小说的写作问题

收到鬼古女寄来的最新小说《伤心至死万劫》&#xff0c;这是他第三部长篇&#xff0c;上海人民出版社2005年10月出版&#xff0c;也是他《伤心至死》悬疑系列的第一部。我和鬼古女只在网上有过交流&#xff0c;据说这是一对旅居美国的神秘夫妇的笔名。我喜欢他的小说&#xff0…