加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MySql教程 > 正文

Mysql实例在MySQL中使用STRAIGHT_JOIN的教程

发布时间:2020-12-12 01:13:04 所属栏目:MySql教程 来源:网络整理
导读:《Mysql实例在MySQL中使用STRAIGHT_JOIN的教程》要点: 本文介绍了Mysql实例在MySQL中使用STRAIGHT_JOIN的教程,希望对您有用。如果有疑问,可以联系我们。 MYSQL数据库 问题 MYSQL数据库 ?? 通过「SHOW FULL PROCESSLIST」语句很容易就能查到问题SQL,如下:

《Mysql实例在MySQL中使用STRAIGHT_JOIN的教程》要点:
本文介绍了Mysql实例在MySQL中使用STRAIGHT_JOIN的教程,希望对您有用。如果有疑问,可以联系我们。

MYSQL数据库问题

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

MYSQL数据库
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

MYSQL数据库?? 说明:因为post和tag是多对多的关系,所以存在一个关联表post_tag.

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

MYSQL数据库
+----------+---------+-------+-----------------------------+
| table  | key   | rows | Extra            |
+----------+---------+-------+-----------------------------+
| post_tag | tag_id | 71220 | Using where; Using filesort |
| post   | PRIMARY |   1 | Using where         |
+----------+---------+-------+-----------------------------+

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

MYSQL数据库
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

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

MYSQL数据库
+----------+----------------+--------+-------------+
| table  | key      | rows  | Extra    |
+----------+----------------+--------+-------------+
| post   | status_created | 119340 | Using where |
| post_tag | post_id    |   1 | Using where |
+----------+----------------+--------+-------------+

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

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

MYSQL数据库?? 这一切还得从MySQL对多表连接的处理方式说起,首先要确定以谁为驱动表,也就是说以哪个表为基准,在处理此类问题时,MySQL优化器采用了简单粗暴的解决方法:哪个表的结果集小,就以哪个表为驱动表,通常这都是最佳选择.

MYSQL数据库?? 说明:在EXPLAIN结果中,第一行出现的表就是驱动表.

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

  1. ??? 以post为驱动表,通过status_created索引过滤,结果集119340行
  2. ??? 以post_tag为驱动表,通过tag_id索引过滤,结果集71220行

MYSQL数据库?????? 显而易见,post_tag过滤的结果集更小,所以MySQL优化器选择它作为驱动表,可悲催的是我们还需要以post表中的created字段来排序,也就是说排序字段不在驱动表里,于是乎不可避免的出现了「Using filesort」,从而导致慢查询.

MYSQL数据库?????? 知道了来龙去脉,优化起来就容易了.头等大事是务必保证排序字段在驱动表中,所以必须以post是驱动表,于是乎「STRAIGHT_JOIN」就成了答案,它强制了连接顺序.

MYSQL数据库?????? …

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读