今天給大家下另一個性能提升神器-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類似,但能讓左邊的表來驅動右邊的表,能改表優化器對於聯表查詢的執行順序。
接下來我們舉個例子進行大致的分析:
select t1.*
from Table1 t1 inner join Table2 t2 on t1.CommonID = t2.CommonID where t1.FilterID = 1
以上sql大數據量下執行需要30s,是不是很奇怪?明明Table1表的FilterID字段建了索引啊,Table1和Table2的CommonID也建了索引啊。通過explain來分析,你會發現執行計划中表的執行順序是Table2->Table1。這個時候要略微介紹下驅動表的概念,mysql中指定了連接條件時,滿足查詢條件的記錄行數少的表為驅動表;如未指定查詢條件,則掃描行數少的為驅動表。mysql優化器就是這么粗暴以小表驅動大表的方式來決定執行順序的。
但如下sql的執行時間都少於1s:
select t1.*
from Table1 t1 where t1.FilterID = 1
或
select t1.*
from Table1 t1 inner join Table2 t2 on t1.CommonID = t2.CommonID
這個時候STRAIGHT_JOIN就派上用場,我們對sql進行改造如下:
select t1.*
from Table1 t1 STRAIGHT_JOIN Table2 t2 on t1.CommonID = t2.CommonID where t1.FilterID = 1
用explain進行分析,發現執行順序為Table1->Table2,這時就由Table1來作為驅動表了,Table1中相應的索引也就用上了,執行時間竟然低於1s了。
分析到這里,必須要重點說下:
- STRAIGHT_JOIN只適用於inner join,並不使用與left join,right join。(因為left join,right join已經代表指定了表的執行順序)
- 盡可能讓優化器去判斷,因為大部分情況下mysql優化器是比人要聰明的。使用STRAIGHT_JOIN一定要慎重,因為啊部分情況下認為指定的執行順序並不一定會比優化引擎要靠譜。
擴展閱讀:
https://stackoverflow.com/questions/512294/when-to-use-straight-join-with-mysql