sql語句性能如何優化
查詢速度慢的原因很多,常見如下幾種:
1、沒有索引或者沒有用到索引(這是查詢慢最常見的問題,是程序設計的缺陷)
2、I/O吞吐量小,形成了瓶頸效應。
3、沒有創建計算列導致查詢不優化。
4、內存不足
5、網絡速度慢
6、查詢出的數據量過大(可以采用多次查詢,其他的方法降低數據量)
7、鎖或者死鎖(這也是查詢慢最常見的問題,是程序設計的缺陷)
8、sp_lock,sp_who,活動的用戶查看,原因是讀寫競爭資源。
9、返回了不必要的行和列
10、查詢語句不好,沒有優化
sql語句的優化
由于SQL優化起來比較復雜,并且還會受環境限制,在開發過程中,寫SQL必須必須要遵循以下幾點的原則: *采用自下而上的順序解析WHERE子句,根據這個原理,表之間的連接必須寫在其他WHERE條件之前, 那些可以過濾掉最大數量記錄的條件必須寫在WHERE子句的末尾. 例如: (低效) SELECT … FROM EMP E WHERE SAL > 50000 AND JOB = 'MANAGER' AND 25 < (SELECT COUNT(*) FROM EMP WHERE MGR=*); (高效) SELECT … FROM EMP E WHERE 25 < (SELECT COUNT(*) FROM EMP WHERE MGR=*) AND SAL > 50000 AND JOB = 'MANAGER'; *子句中避免使用'*' 當在SELECT子句中列出所有的COLUMN時,使用動態SQL列引用 ‘*’ 是一個方便的方法.可是,這是一個非常低效的方法. 實際上,ORACLE在解析的過程中, 會將'*' 依次轉換成所有的列名, 這個工作是通過查詢數據字典完成的, 這意味著將耗費更多的時間. 3.使用表的別名(Alias) 當在SQL語句中連接多個表時, 請使用表的別名并把別名前綴于每個Column上.這樣一來,就可以減少解析的時間并減少那些由Column歧義引起的語法錯誤. 注:Column歧義指的是由于SQL中不同的表具有相同的Column名,當SQL語句中出現這個Column時,SQL解析器無法判斷這個Column的歸屬。
怎樣進行sql數據庫的優化
通過8個方法優化Mysql數據庫:創建索引、復合索引、索引不會包含有NULL值的列、使用短索引、排序的索引問題、like語句操作、不要在列上進行運算、不使用NOT IN和<>操作1、創建索引對于查詢占主要的應用來說,索引顯得尤為重要。
很多時候性能問題很簡單的就是因為我們忘了添加索引而造成的,或者說沒有添加更為有效的索引導致。如果不加索引的話,那么查找任何哪怕只是一條特定的數據都會進行一次全表掃描,如果一張表的數據量很大而符合條件的結果又很少,那么不加索引會引起致命的性能下降。
但是也不是什么情況都非得建索引不可,比如性別可能就只有兩個值,建索引不僅沒什么優勢,還會影響到更新速度,這被稱為過度索引。2、復合索引比如有一條語句是這樣的:select * from users where area='beijing' and age=22;如果我們是在area和age上分別創建單個索引的話,由于mysql查詢每次只能使用一個索引,所以雖然這樣已經相對不做索引時全表掃描提高了很多效率,但是如果在area、age兩列上創建復合索引的話將帶來更高的效率。
如果我們創建了(area, age, salary)的復合索引,那么其實相當于創建了(area,age,salary)、(area,age)、(area)三個索引,這被稱為最佳左前綴特性。因此我們在創建復合索引時應該將最常用作限制條件的列放在最左邊,依次遞減。
3、索引不會包含有NULL值的列只要列中包含有NULL值都將不會被包含在索引中,復合索引中只要有一列含有NULL值,那么這一列對于此復合索引就是無效的。所以我們在數據庫設計時不要讓字段的默認值為NULL。
4、使用短索引對串列進行索引,如果可能應該指定一個前綴長度。例如,如果有一個CHAR(255)的 列,如果在前10 個或20 個字符內,多數值是惟一的,那么就不要對整個列進行索引。
短索引不僅可以提高查詢速度而且可以節省磁盤空間和I/O操作。5、排序的索引問題mysql查詢只使用一個索引,因此如果where子句中已經使用了索引的話,那么order by中的列是不會使用索引的。
因此數據庫默認排序可以符合要求的情況下不要使用排序操作;盡量不要包含多個列的排序,如果需要最好給這些列創建復合索引。6、like語句操作一般情況下不鼓勵使用like操作,如果非使用不可,如何使用也是一個問題。
like “%aaa%” 不會使用索引而like “aaa%”可以使用索引。7、不要在列上進行運算select * from users where YEAR(adddate)<2007;將在每個行上進行運算,這將導致索引失效而進行全表掃描,因此我們可以改成select * from users where adddate<'2007-01-01';8、不使用NOT IN和<>操作NOT IN和<>操作都不會使用索引將進行全表掃描。
NOT IN可以NOT EXISTS代替,id<>3則可使用id>3 or id<3來代替。
怎樣優化SQL語句提高效率
我們要做到不但會寫SQL,還要做到寫出性能優良的SQL語句。
(1)選擇最有效率的表名順序(只在基于規則的優化器中有效): Oracle的解析器按照從右到左的順序處理FROM子句中的表名,FROM子句中寫在最后的表(基礎表 driving table)將被最先處理,在FROM子句中包含多個表的情況下,您必須選擇記錄條數最少的表作為基礎表。 假如有3個以上的表連接查詢, 那就需要選擇交叉表(intersection table)作為基礎表, 交叉表是指那個被其他表所引用的表。
(2)WHERE子句中的連接順序: Oracle采用自下而上的順序解析WHERE子句,根據這個原理,表之間的連接必須寫在其他WHERE條件之前, 那些能夠過濾掉最大數量記錄的條件必須寫在WHERE子句的末尾。 (3)SELECT子句中避免使用‘*’: Oracle在解析的過程中, 會將‘*’依次轉換成任何的列名, 這個工作是通過查詢數據字典完成的, 這意味著將耗費更多的時間。
(4)減少訪問數據庫的次數: Oracle在內部執行了許多工作: 解析SQL語句, 估算索引的利用率, 綁定變量 , 讀數據塊等。 (5)在SQL*Plus , SQL*Forms和Pro*C中重新配置ARRAYSIZE參數, 能夠增加每次數據庫訪問的檢索數據量 ,建議值為200。
(6)使用DECODE函數來減少處理時間: 使用DECODE函數能夠避免重復掃描相同記錄或重復連接相同的表。 (7)整合簡單,無關聯的數據庫訪問: 假如您有幾個簡單的數據庫查詢語句,您能夠把他們整合到一個查詢中(即使他們之間沒有關系)。
(8)刪除重復記錄: 最高效的刪除重復記錄方法 ( 因為使用了ROWID)例子: DELETE FROM EMP E WHERE E。 ROWID > (SELECT MIN(X。
ROWID) FROM EMP X WHERE X。EMP_NO = E。
EMP_NO); (9)用TRUNCATE替代DELETE: 當刪除表中的記錄時,在通常情況下, 回滾段(rollback segments ) 用來存放能夠被恢復的信息。 假如您沒有COMMIT事務,ORACLE會將數據恢復到刪除之前的狀態(準確地說是恢復到執行刪除命令之前的狀況) 而當運用TRUNCATE時, 回滾段不再存放任何可被恢復的信息。
當命令運行后,數據不能被恢復。因此很少的資源被調用,執行時間也會很短。
(TRUNCATE只在刪除全表適用,TRUNCATE是DDL不是DML)。 以上是我對于這個問題的解答,希望能夠幫到大家。