實際工作中,我們每個人難免都會要寫sql,執行sql,但是有時時候執行非常慢,甚至獲得不了結果。這時候你會怎麼辦?放棄?去苦口婆心的求隔壁房間鬍子擦擦的猥瑣dba大叔?
no,正確方法是先檢查一下你的sql語句。本文蟲蟲給你列出來用來排查sql查詢比較慢的常見方法和對策。文中所有方法和例子均基於postgresql,當然這些都可以快速移植到mysql和其他資料庫,因為sql語句基本上都是相通的。
對策:
可以通過詢問資料庫來了解資料庫當前狀態。不需要你去@ dba或者運維,你只需執行sql語句就可以獲得這些資訊:
我們可以通過以下語句列出當前所有執行的和空閒的查詢:
select * from pg_stat_activity
下面的語句查詢導致鎖表的查詢:
select pid,usename,pg_blocking_pids(pid) as blocked_by,query as blocked_query from pg_stat_activity where cardinality(pg_blocking_pids(pid))> 0;
表當時正在更新嗎?如果你查詢時候恰好遇到etl程序在更新被鎖定的表,你也就無法對其查詢。
對策:
了解這些etl更新執行時間,避開這些時間再執行查詢。
知道了當前資料庫的狀態。現在可以具體從你的sql語句入手了。首先看你的sql語句:select * from ***
咦,為啥要 select * ?
對策:
如果知識為了了解表的結構,請從模式樹獲取表字段。
d 表名
為了執行更快,只select具體的字段值,不要用select * ;
如果有乙個特別大的表或寬表(表示字段很多),查詢引擎不可能將所有資料都取過來。使用'limit'來限制查詢,如果你確實需要關注每一行的內容那另說;
如果要count計算,不要執行查詢通過查詢結果底部統計行數來獲取統計,請使用計算行數的子查詢:
postgresql是區分大小寫的,這對於windows下使用者習慣sql serve的人來說可能有點彆扭。
對策:
如果"小寫化"或"大寫化"資料,比較費勁,在將資料加入查詢中之前,先檢視欄位的形式。
如果在join時候需求,請僅在join一側使用;嘗試使用ilike進行不區分大小寫的匹配。
盡量避免使用"in"或"not in"。此操作需要全表掃瞄,查詢引擎需要對比每一行資料以檢查是否滿足條件。
對策:
嘗試使用"except"或"not exists",這些對查詢計畫的影響遠小於"not in"。
cte(公共表示式)比子查詢更易於閱讀,但在postgresql中該角色優化有限,查詢優化器無法對其變動約束條件實現查詢優化。
對策:
cte和子查詢雖然都很有用,但是都有其適用範圍。使用cte時候請考慮表大小,可能返回的行數以及寫入時在cte中執行的操作。
在like的開頭和結尾使用萬用字元會降低查詢效率。並且可能會獲得比預期更多的結果。
對策:
在必需地方使用萬用字元,通常簡易,只在like後的開頭或者結尾一端使用:
將幾個巢狀查詢用作函式進行操作非常昂貴,這時候嘗試寫入表會更快。
對策:
如果流程有很多步驟,請考慮建立臨時表,以便加入較小的資料子集。
檢視是引用查詢執行的查詢結果。如果要呼叫多個檢視,或者更複雜情況下訪問檢視的檢視,要求查詢引擎執行多個查詢返回結果。
對策:
如果需要每天/每週/每月等定期的查詢快照,不是動態過濾的查詢檢視,請使用定期結果入錶,而不要用檢視。
如果要使用巢狀檢視,請考慮是否有更直接的方法通過編寫查詢來獲取所需的結果,不要使用多個查詢的巢狀檢視。
索引通過對資料字段序列化來加速查詢,可以以讓資料庫引擎快速定位資料的位置。索引型別決定了索引的工作方式。
對策:
對資料表中需要經常查詢的,使用頻繁的字段(或者字段組合)加索引。
評估表中現存的索引確保表中沒有太多的索引或者有無用的索引。
本文列出了sql查詢中常見可能會導致效能問題事項,並提供具體對策用以優化。當然這些只是給出了一般性質的建議,針對具體問題具體分析才是解決問題的關鍵。
常見的萬用字元 SQL常見萬用字元使用指南
萬用字元是用來匹配值的一部分的特殊字元,實際是sql中的where子句中有特殊含義的字元。找出所有id以ac開頭的產品,表示任意字元出現任意次數。相當於你告訴sql,幫我找到 ac 可以是任何東西。同理 where prod id like ac 代表ac可以出現在任何位置,只要出現了ac就匹配。w...
mysql常見慢sql mysql 慢SQL分析
開啟慢sql記錄 為什麼要開啟慢sql記錄 mysql在執行過程中,某些sql可能會執行較長時間,我們通過配置一些東西,把這些sql記錄下來,以便我們分析和優化sql。首先先檢視是否已經開啟了記錄設定 mysql show variables like query variable name val...
MySQL常見問題之SQL查詢慢
可能是經常處理業務,最近總是聽到開發的同學說sql的查詢慢。然後問我為什麼,讓我在資料庫層面找原因。這樣的需求接的多了,對於這類需求,我已經有了一套比較官方的回答思路,我來說,大家看,看看還有什麼沒有考慮到的地方,歡迎指正。首先,當有業務方對我說sql查詢慢的時候,一般我會先問幾個問題 1 這個sq...