MySQL外鍵關聯大表和小表應該怎麼驅動

看了網上的一些文章,有的人說大表驅動小表查詢更快,有的人說小表關聯大表更快。

比如:

有人支持小表關聯大表

有人支持大表關聯小表

這兩種觀點把我也整蒙了,到底應該大表關聯小表,還是應該小表關聯大表呢?

我先給出我的結論:大表驅動小表

爲什麼這麼說呢?實踐是檢驗真理的唯一標準。動手自己測一測就知道了。

新建了兩張表:

big_table,顧名思義就是數據量較大的table,數據量大概在50W左右,表結構和數據在下面

sid關聯到small_table的主鍵id。

small_table,即相對較小的table,數據量在2W左右,表結構和數據在下面

沒有特別說明的話後文b表代指big_table,s表代指small_table。

實驗開始

第一步:大表關聯小表

SELECT * FROM big_table b LEFT JOIN small_table s ON s.id = b.sid LIMIT 0,500000;

結果:

多測試幾次,時間也都穩定在零點幾秒。

貼出執行計劃:

從執行計劃可以看出Nested loop join的基準表是b(外循環),s是內循環。

第二步:小表關聯大表

SELECT * FROM small_table s LEFT JOIN big_table b ON s.id = b.sid LIMIT 0,10000;

這裏爲什麼不limit50W呢?因爲太慢了,我也很難受。。。取1W看結論。

結果:

可以看到時間明顯比第一步的時間更長,而且還僅僅是1W的數據量。

執行計劃:

可以看到Nested loop join的基準表是s(外循環),b是內循環。這裏和第一步執行計劃不同的是:第一步執行計劃查詢s表使用了索引,即主鍵索引,而第二步查詢b表使用的全表掃描(ALL)。如果給b表的sid列添加索引結果會怎麼樣呢?

結果一目瞭然,加了索引之後速度明顯變快。

那麼繼續執行50w的數據查詢,結果是什麼呢?

執行計劃和查詢1w數據量是一樣的。

結果分析

根據控制變量的觀點,第一步內循環採用主鍵查詢,而第二步採用索引查詢。這可能是第二步查詢時間更長的原因,如果控制變量使第二步也採用主鍵查詢的方式,那麼s表數據量也必須擴展到50W,那麼熟前熟後就沒有意義了!即使是因爲主鍵和索引帶來的時間差異,也可以認爲大表在前的查詢速度更快,當然也可能是因爲內部循環數據量更小,查詢速度更快。

綜上所訴,大表驅動小表(從表驅動主表,外鍵表驅動主鍵表)更快

主表驅動從表應該在從表的外鍵上建立索引。

說那麼多,實際情況下有可能不是主鍵關聯,沒有建立索引等等,因此看執行計劃纔是王道!!

PS)做這個實驗的時候我心裏也是沒底的,不知道大表驅動小表更快還是小表驅動大表更快,所以我最前面的結果也是改了幾次。這個結論只是半個下午實驗出來的,可能存在一定的侷限性!測試的條件可能存在缺陷,希望有人能提出不同的觀點。

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章