除夕送你10條高性能SQL優化方案

愛數據網 發佈 2020-01-25T17:14:13+00:00

例如:SELECTname FROM employee WHERE salary > 60000在這條語句中,如salary欄位是money型的,則優化器很難對其進行優化,因為60000是個整型數。

描 述

報表的核心是數據,數據集是否合理決定報表的質量。

1. 每張報表都應該有一個主數據集,為了降低維護時的工作量,儘量將所有欄位置於主數據集,除非在某些情況下,不使用多源數據集會導致主數據集異常複雜。

2. 在製作報表之前,儘量考慮到所有需要展示的數據欄位,在資料庫軟體中,合理編寫sql語句,大數據情況儘量對sql做優化,以及添加索引。

擁有高性能SQL查詢語句,能使查詢速度加快,報表展示速度得到較明顯的提升!

方案介紹

1. SELECT子句中避免使用 「*」

當你想在SELECT子句中列出所有的COLUMN時,使用動態SQL列引用『』是一個方便的方法。不幸的是,這是一個非常低效的方法。實際上,ORACLE在解析的過程中, 會將「」 依次轉換成所有的列名, 這個工作是通過查詢數據字典完成的, 這意味著將耗費更多的時間。

2. 刪除重複記錄

最高效的刪除重複記錄方法 ( 因為使用了ROWID)

DELETE FROM EMP E WHERE E.ROWID > (SELECT MIN(X.ROWID) FROM EMP X WHERE X.EMP_NO = E.EMP_NO)

3. 計算記錄條數

和一般的觀點相反, count(*) 比count(1)稍快 ,當然如果可以通過索引檢索,對索引列的計數仍舊是最快的。例如 COUNT(EMPNO)

4. 用EXISTS替換DISTINCT

當提交一個包含一對多表信息(比如部門表和雇員表)的查詢時,避免在SELECT子句中使用DISTINCT。一般可以考慮用EXIST替換,EXISTS 可以使查詢更為迅速。例如:Sql代碼。

--低效:

SELECT DISTINCT DEPT_NO,DEPT_NAME FROM DEPT D,EMP E WHERE D.DEPT_NO = E.DEPT_NO

--高效:

SELECT DEPT_NO,DEPT_NAME FROM DEPT D WHERE EXISTS ( SELECT 『X』 FROM EMP E WHERE E.DEPT_NO = D.DEPT_NO)

5. 應儘量避免在 where 子句中對欄位判斷!

比如:

select id from t where num is 

可以在num上設置默認值0,確保表中num列沒有值,然後這樣查詢:

select id from t where num=0

6. 應避免在 where 子句中使用!=或<>操作符!

將引擎放棄使用索引而進行全表掃描。優化器將無法通過索引來確定將要命中的行數,因此需要搜索該表的所有行。

7. in 和 not in 也要慎用

因為IN會使系統無法使用索引,而只能直接搜索表中的數據。如:

select id from t where num in(1,2,3)

對於連續的數值,能用 between 就不要用 in 了:

select id from t where num between 1 and 3

8. 不要在 where 子句中的「=」左邊運算

進行函數、算術運算或其他表達式運算,系統將可能無法正確使用索引。

9. 避免使用不兼容的數據類型

例如float和int、char和varchar、binary和varbinary是不兼容的。數據類型的不兼容可能使優化器無法執行一些本來可以進行的優化操作。例如:

SELECT name FROM employee WHERE salary > 60000

在這條語句中,如salary欄位是money型的,則優化器很難對其進行優化,因為60000是個整型數。我們應當在編程時將整型轉化成為錢幣型,而不要等到運行時轉化。

10. 能用DISTINCT的就不用GROUP BY

SELECT OrderID FROM Details WHERE UnitPrice > 10 GROUP BY OrderID

可改為:

SELECT DISTINCT OrderID FROM Details WHERE UnitPrice > 10

End.

作者:叫我老村長

來源:簡書

關鍵字: