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


  有好多時候,我們常聽別人說大表在前,小表在后,包括現在好多百度出來的靠前的答案都有說數據庫是從右到左加載的,所以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為小表在前)

  

  

  執行完后。我們驚奇的發現,居然他們耗費的資源和時間基本是一模一樣的,所以說這個表的順序會影響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,小表在前)

  

  

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM