SQL常用優化手法

1.創建必要的索引

   在經常檢索的字段上創建索引,創建索引會給檢索帶來巨大的性能提升,因此在發現檢索速度過慢的時候應該首先想到就是創建索引。

 

2.使用預編譯查詢

   程序通常根據用戶輸入動態執行SQL語句,這個時候應該儘量使用參數化SQL,這樣不僅可以避免SQL注入漏洞攻擊,最重要的事數據庫會對這些參數化SQL執行預編譯。這樣,第一次執行的時候DBMS會爲這個SQL語句進行查詢優化並且執行預編譯,以後再執行這個SQL的時候就直接使用預編譯的結果,這樣可以大大的提高執行的速度。

 

3.調整Where子句中的連接順序

    DBMS一般採用自下而上的順序解析Where子句,根據這個原理,表連接最好寫在其他的Where條件之前,這樣就可以過濾掉最大的數據記錄。

    如下面的SQL性能較差:

     select * from T_Person

      Where FSalary > 50000

      AND FPosition = 'Manager'

      AND 25 < (select  count(*)from T_Manager where ID = T_Person.FmanagerID)

  我們將子句移到前面,這樣的SQL性能比較好:

     select * from T_Person

      Where 25 < (select  count(*)from T_Manager where ID = T_Person.FmanagerID)

      AND  FSalary > 50000

      AND FPosition = 'Manager'

     

4.Select 語句中避免使用*

   “Select *” 比較簡單,但是除非真的需要檢索所有的列,否則這樣將檢索出不需要的列,增加網絡負載和服務器的資源消耗。即使確實需要檢索所有的列,也不要使用select *,因爲這個是一個非常低效的方法,DBMS在解析的過程中,會將* 依次轉換成所有的列名,這意味着將耗費更多的時間。

 

5.儘量將多條SQL語句壓縮到一句SQL中

   每次執行SQL的時候都要建立網絡連接,進行權限校驗,進行SQL語句的查詢優化,發送執行結果,這個過程是很耗時的,因此應該儘量避免過多的執行SQL語句,能夠壓縮到一句SQL執行的語句就不要用多條來執行。

 

6.用Where子句中替換Having子句

   要避免使用Having子句,因爲Having只會在檢索出所有的記錄之後纔對結果集進行過濾。如果能通過Where子句限制記錄的數目,那就能減少這方面的開銷。Having中的條件一般用於聚合函數的過濾,除此之外,應該將條件寫在Where子句中。

 

7.使用表的別名

   當在SQL語句中有連接多個表的時候,請使用表的別名並把別名的前綴置於每個列名上,這樣就可以減少解析的時間並減少那些有列名歧義引起的語法錯誤。

 

8. 用EXISTS 替代IN

    在查詢中,爲了滿足一個條件,往往需要對另一個表進行連接,在這種情況下,使用EXISTS而不是使用IN,通常將提高查詢效率,因爲IN子句將執行一個子查詢內部的排序和合並。下面的語句2就比語句1效率更高。

   語句1:

     select * from T_Employee

     where FNumber > 0 and FDEPTNO in (select FNumber from T_Department where FmanagerName = 'Tom')

 

  語句2:

   select * from T_Employee where FNumber > 0

and EXIESTS (select 1 from T_Department were T_Department.ID = T_Empoyee.FDEPTNO  and Fmanagement = 'Tom')

 ( ************************       子查詢表大的用exists,子查詢表小的用in    *************************************)

9.用表連接替換EXISTS

   通常來說,表連接方式比EXISTS更有效率,下面的語句比上面的語句2 效率更高

   select T_Employee.* from T_Employee ,T_Department d

  where T_Employee.FNumber > 0 and T_Department.ID = T_Empoyee.FDEPTNO  and d.Fmanagement = 'Tom'

 

10.避免在索引列上使用計算

   在Where子句中,如果索引列是計算或者函數的一部分,DBMS優化器將不會使用索引而使用全表掃描。

 

 11.用UNION ALL替換UNION

     當SQL語句需要UNION兩個查詢結果集合的時候,即使檢索結果中不會有重複的記錄,使用UNION這兩個結果集同樣會嘗試合併結果,然後輸出最終結果前進行排序。因此,如果檢索結果中不會有重複記錄的話,應該用UNION ALL替換UNION,這樣效率更高。

 

 12.避免隱式類型轉換造成全表掃描

      Select FID,FAGE,FNAME from T_Person where FAGE =10 (注意“FAGE爲String類型的)

在這個SQL語句中,將字符串類型字段FLevel與數值10 進行比較,由於大部分數據庫的隱式轉換類型中數值類型的優先級高於字符串類型,因此DBMS會對FAGE字段進行隱式類型轉換,相當於執行:

       Select FID,FAGE,FNAME from T_Person where TO_INT(FAGE) =10

  所以應該這樣寫:  Select FID,FAGE,FNAME from T_Person where FAGE = ’10‘

 

 

13.防止檢索範圍過寬

   如果DBMS優化器認爲檢索範圍過寬,那麼它將放棄索引查找而使用全表掃描,下面可能造成檢索範圍過寬的情況:

   (1)使用IS NOT NULL或者不等於判斷,可能造成優化器假設匹配的記錄數太多。

   (2)使用LIEK的時候,"a%"將會使用索引,而"a%c" 和 "%c" 則會使用全表掃描,因此"a%c" 和 "%c" 不能被有效的評估匹配的數量。

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