MySQL中Nested-Loop Join算法小結。本站提示廣大學習愛好者:(MySQL中Nested-Loop Join算法小結)文章只能為提供參考,不一定能成為您想要的結果。以下是MySQL中Nested-Loop Join算法小結正文
不知不覺的玩了兩年多的MySQL,發明許多人都說MySQL比較Oracle來講,優化器做的比擬差,其實某種水平下去說確切是如許,然則究竟MySQL才到5.7版本,Oracle都曾經成長到12c了,明天我就看了看MySQL的銜接算法,嗯,如今來講照樣不支撐Hash Join,只要Nested-Loop Join,那明天就總結一下我進修的心得吧。
Nested-Loop Join根本算法完成,偽代碼是如許:
for each row in t1 matching range { for each row in t2 matching reference key { for each row in t3 { if row satisfies join conditions, send to client } } }
這段代碼很簡略,固然我也不怎樣會寫代碼,然則我照樣看得懂的。這裡假定有三張表,t1, t2, t3,這段代碼,分離會展示出explain籌劃裡的range, ref和ALL,表示在SQL履行籌劃層裡,t3就會停止一次全表掃描,我明天在這個處所看到了一個很妖的優化SQL辦法,Straight-join:http://hidba.ga/2014/09/26/join-query-in-mysql/,個中提到了驅動表的概念,那末對應過去,驅動表就是偽代碼裡的t3表,博文裡說MySQL會主動選擇成果集最小的表作為驅動表,作為算法剖析,如許選擇驅動表確切是消費最小的方法。那末這裡還提到了,經由過程減少驅動表成果集停止銜接優化,那末依據這個算法來看,成果集較小的驅動表確切可使輪回次數削減。
固然了,MySQL本身在這個算法基本上,演進出了Block Nested-Loop join算法,其實根本上和下面的算法沒有差別,偽代碼以下:
for each row in t1 matching range { for each row in t2 matching reference key { store used columns from t1, t2 in join buffer if buffer is full { for each row in t3 { for each t1, t2 combination in join buffer { if row satisfies join conditions, send to client } } empty buffer } } } if buffer is not empty { for each row in t3 { for each t1, t2 combination in join buffer { if row satisfies join conditions, send to client } } }
這個算法,將外層輪回的數據緩存在join buffer中,內層輪回中的表回合buffer中的數據停止比較,從而削減輪回次數,如許即可以進步效力。官網上有個example,我有點沒有看明確:假如有10行被緩存到了buffer裡,這10行被傳給了內層輪回,內層輪回的一切行都邑和buffer中的這10行停止比較。原文是如許的:
For example, if 10 rows are read into a buffer and the buffer is passed to the next inner loop, each row read in the inner loop can be compared against all 10 rows in the buffer
假如S指的是t1, t2組合在緩存中的年夜小,C是這些組合在buffer中的數目,那末t3表被掃描的次數應當是:
(S * C)/join_buffer_size + 1
依據這個算式,join_buffer_size越年夜,掃描的次數越小,假如join_buffer_size到了能緩存一切之前的行組合,那末這時候就是機能最好的時刻,以後再增年夜也就沒有甚麼後果了。
在有索引的情形下,MySQL會測驗考試去應用Index Nested-Loop Join算法,在有些情形下,能夠Join的列就是沒有索引,那末這時候MySQL的選擇相對不會是最早引見的Simple Nested-Loop Join算法,由於誰人算法太粗魯,不忍直視。數據量年夜些的龐雜SQL估量幾年都能夠跑不出成果,假如你不信,那就是too young too simple。或許Inside君可以給你些SQL跑跑看。
Simple Nested-Loop Join算法的缺陷在於其關於內表的掃描次數太多,從而招致掃描的記載太甚宏大。Block Nested-Loop Join算法較Simple Nested-Loop Join的改良就在於可以削減內表的掃描次數,乃至可以和Hash Join算法一樣,僅需掃描內表一次。