今天給大家下另一個性能提升神器-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」,綜合來看,性能依然得到了提升。