關於數據庫優化2——關於表的連接順序,和where子句的前後順序,是否會影響到sql的執行效率問題

SQL 技術 達人科技 2017-06-23

有好多時候,我們常聽別人說大表在前,小表在後,包括現在好多百度出來的靠前的答案都有說數據庫是從右到左加載的,所以from語句最後關聯的那張表會先被處理。如果三表交叉,就選擇交叉表來作為基礎表。等等一些結論,但是這些真的正確麼?我就回家做了一個小的驗證,來看一看到底是怎麼一回事。(博主作實驗用的是Oracle,但是不代表只是Oracle是這樣的原理,現在大部分的關係型數據庫都是一樣的)

首先我們來執行一下以下的sql語句,來看一下執行計劃。看一看到底是怎麼樣的。

1 drop table tab_big; --刪除原有big表
2 drop table tab_small;
3 create table tab_big  as select * from dba_objects where rownum<=30000;  --創建表,並且插入記錄
4 create table tab_small  as select * from dba_objects where rownum<=10;
5 set autotrace traceonly --開啟執行計劃和統計信息
6 set linesize 1000
7 set timing on 
8 select count(*) from tab_big,tab_small;  
9 select count(*) from tab_small,tab_big;

OK,完事後咱們來看一看,到底表的順序到底是否會影響到數據庫的執行效率,我們來看一下”select count(*) from tab_big,tab_small“和”select count(*) from tab_small,tab_big“的執行計劃(圖1為大表在前,小表在後。圖2為小表在前)

關於數據庫優化2——關於表的連接順序,和where子句的前後順序,是否會影響到sql的執行效率問題關於數據庫優化2——關於表的連接順序,和where子句的前後順序,是否會影響到sql的執行效率問題

執行完後。我們驚奇的發現,居然他們耗費的資源和時間基本是一模一樣的,所以說這個表的順序會影響sql的執行效率是一個不對的結論,但是大部分網上評論和博客都是這麼寫的,真的是惡意謠言麼?那咱們看一下下面這兩條sql的執行效率。

然後我們執行下,下面的這兩條sql。

1 select /*+rule*/ count(*) from tab_big,tab_small;--/*+rule*/基於規則執行
2 select /*+rule*/ count(*) from tab_small,tab_big;

接下來我們看一下這兩條sql的執行計劃。(圖1為第一條sql大表在前,小表在後,圖2為第二條sql,小表在前)

關於數據庫優化2——關於表的連接順序,和where子句的前後順序,是否會影響到sql的執行效率問題關於數據庫優化2——關於表的連接順序,和where子句的前後順序,是否會影響到sql的執行效率問題

這個時候我們有驚奇的發現,這個就應了網上大部分的答案,說明他們說的也是有道理的。這其中是什麼原因呢?根據我在翻閱各種資料和查閱官網後得知:原來早些的數據庫版本是基於規則去處理的sql,也就是加上我們的/*+rule*/這個之後。但是現在我們的數據庫都是基於代價的,所以也就不存在了表的順序會影響sql的效率了。那我們的where其實也是一樣的道理,也不會因為順序去影響sql的效率。(where的結論博主也經過了執行驗證,但是同理表連接,所以就不貼出來代碼了)