今天给大家下另一个性能提升神器-STRAIGHT_JOIN,在数据量大的联表查询中灵活运用的话,能大大缩短查询时间。
首先来解释下STRAIGHT_JOIN到底是用做什么的:
STRAIGHT_JOIN is similar to JOIN, except that the left table is always read before the right table.
This can be used for those (few) cases for which the join optimizer puts the tables in the wrong order.
意思就是说STRAIGHT_JOIN功能同join类似,但能让左边的表来驱动右边的表,能改表优化器对于联表查询的执行顺序。
mysql多表关联查询优化器
首先MySQL优化器要确定以谁为驱动表,也就是说以哪个表为基准,在处理此类问题时,MySQL优化器采用了简单粗暴的解决方法:哪个表的结果集小,就以哪个表为驱动表,当然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
说明:因为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」,综合来看,性能依然得到了提升。