sql優化處理總匯

2021-08-07 12:07:33 字數 3174 閱讀 8372

1、沒有索引或者沒有用到索引。

經常會用到這樣問題這個地方該不該用索引?這個問題等下說先了解下索引。當你新增個索引的時候首先建立乙個索引檔案。一般來說,在where和join中出現的列需要建立索引,但也不完全如此,因為mysql只對<,<=,=,>,>=,between,in,以及某些時候的like才會使用索引。因為在以萬用字元%和_開頭作查詢時,mysql不會使用索引。
索引的注意事項以下的情況是不會使用索引的即使你設定的索引。

1.索引包含有null值的列。

2.在列上進行運算。

3.使用not in和<>操作。

下列幾種情況適合建立索引如何判定是否需要建立索引。

1、較頻繁地作為查詢條件的字段

這個都知道。什麼是教頻繁呢?分析你執行的所有sql語句。最好將他們乙個個都列出來。然後分析,發現其中有些欄位在大部分的sql語句查詢時候都會用到,那麼就果斷為他建立索引。

2、唯一性太差的字段不適合建立索引

什麼是唯一性太差的字段。如狀態字段、型別字段。那些只儲存固定幾個值的字段,例如使用者登入狀態、訊息的status等。這個涉及到了索引掃瞄的特性。例如:通過索引查詢鍵值為a和b的某些資料,通過a找到某條相符合的資料,這條資料在x頁上面,然後繼續掃瞄,又發現符合a的資料出現在了y頁上面,那麼儲存引擎就會丟棄x頁面的資料,然後儲存y頁面上的資料,一直到查詢完所有對應a的資料,然後查詢b欄位,發現x頁面上面又有對應b欄位的資料,那麼他就會再次掃瞄x頁面,等於x頁面就會被掃瞄2次甚至多次。以此類推,所以同乙個資料頁可能會被多次重複的讀取,丟棄,在讀取,這無疑給儲存引擎極大地增加了io的負擔。

3、更新太頻繁地字段不適合建立索引

當你為這個字段建立索引時候,當你再次更新這個字段資料時,資料庫會自動更新他的索引,所以當這個字段更新太頻繁地時候那麼就是不斷的更新索引,效能的影響可想而知。大概被檢索幾十次會更新一次的字段才比較符合建立索引的規範。而如果乙個字段同乙個時間段內被更新多次,那麼果斷不能為他建立索引。

4、不會出現在where條件中的字段不該建立索引

2.盡量少 join

mysql 的優勢在於簡單,但這在某些方面其實也是其劣勢。mysql 優化器效率高,但是由於其統計資訊的量有限,優化器工作過程出現偏差的可能性也就更多。對於複雜的多表 join,一方面由於其優化器受限,再者在 join 這方面所下的功夫還不夠,所以效能表現離 oracle 等關係型資料庫前輩還是有一定距離。但如果是簡單的單錶查詢,這一差距就會極小甚至在有些場景下要優於這些資料庫前輩。
3.盡量少排序

排序操作會消耗較多的 cpu 資源,所以減少排序可以在快取命中率高等 io 能力足夠的場景下會較大影響 sql 的響應時間。對於mysql來說,減少排序有多種辦法,比如:上面誤區中提到的通過利用索引來排序的方式進行優化減少參與排序的記錄條數非必要不對資料進行排序。
4.盡量避免 select *

大多數時候並不會影響到 io 量,但是當我們還存在 order by 操作的時候,select 子句中的字段多少會在很大程度上影響到我們的排序效率。
5.盡量用 join 代替子查詢

雖然 join 效能並不佳,但是和 mysql 的子查詢比起來還是有非常大的效能優勢。mysql 的子查詢執行計畫一直存在較大的問題,雖然這個問題已經存在多年,但是到目前已經發布的所有穩定版本中都普遍存在,一直沒有太大改善。雖然官方也在很早就承認這一問題,並且承諾盡快解決,但是至少到目前為止我們還沒有看到哪乙個版本較好的解決了這一問題。
6.盡量少 or

當 where 子句中存在多個條件以「或」並存的時候,mysql 的優化器並沒有很好的解決其執行計畫優化問題,再加上 mysql 特有的 sql 與 storage 分層架構方式,造成了其效能比較低下,很多時候使用 union all 或者是union(必要的時候)的方式來代替「or」會得到更好的效果。
7.盡量用 union all 代替 union

union 和 union all 的差異主要是前者需要將兩個(或者多個)結果集合並後再進行唯一性過濾操作,這就會涉及到排序,增加大量的 cpu 運算,加大資源消耗及延遲。所以當我們可以確認不可能出現重複結果集或者不在乎重複結果集的時候,盡量使用 union all 而不是 union。

8.盡量早過濾

這一優化策略其實最常見於索引的優化設計中(將過濾性更好的字段放得更靠前)。

在 sql 編寫中同樣可以使用這一原則來優化一些 join 的 sql。比如我們在多個表進行分頁資料查詢的時候,我們最好是能夠在乙個表上先過濾好資料分好頁,然後再用分好頁的結果集與另外的表 join,這樣可以盡可能多的減少不必要的 io 操作,大大節省 io 操作所消耗的時間。

9.避免型別轉換

這裡所說的「型別轉換」是指 where 子句中出現 column 欄位的型別和傳入的引數型別不一致的時候發生的型別轉換:

人為在column_name 上通過轉換函式進行轉換

直接導致 mysql(實際上其他資料庫也會有同樣的問題)無法使用索引,如果非要轉換,應該在傳入的引數上進行轉換

由資料庫自己進行轉換

如果我們傳入的資料型別和字段型別不一致,同時我們又沒有做任何型別轉換處理,mysql 可能會自己對我們的資料進行型別轉換操作,也可能不進行處理而交由儲存引擎去處理,這樣一來,就會出現索引無法使用的情況而造成執行計畫問題。

10.優先優化高併發的 sql,而不是執行頻率低某些「大」sql

對於破壞性來說,高併發的 sql 總是會比低頻率的來得大,因為高併發的 sql 一旦出現問題,甚至不會給我們任何喘息的機會就會將系統壓跨。而對於一些雖然需要消耗大量 io 而且響應很慢的 sql,由於頻率低,即使遇到,最多就是讓整個系統響應慢一點,但至少可能撐一會兒,讓我們有緩衝的機會。

11.從全域性出發優化,而不是片面調整

sql 優化不能是單獨針對某乙個進行,而應充分考慮系統中所有的 sql,尤其是在通過調整索引優化 sql 的執行計畫的時候,千萬不能顧此失彼,因小失大。

12.盡可能對每一條執行在資料庫中的sql進行 explain

優化 sql,需要做到心中有數,知道 sql 的執行計畫才能判斷是否有優化餘地,才能判斷是否存在執行計畫問題。在對資料庫中執行的 sql 進行了一段時間的優化之後,很明顯的問題 sql 可能已經很少了,大多都需要去發掘,這時候就需要進行大量的 explain 操作收集執行計畫,並判斷是否需要進行優化。

關於sql的優化處理

起因程式執行資料錯誤需要修復資料 sql思路 以invalidtime排序,更新最新資料的幾個字段,限制條件為objectid必須為backup am card 20200603中存在的。其中am card表是乙個大表 正式環境估計有幾千萬資料,我這是測試環境資料量沒這麼大 backup am ca...

記憶體優化處理

使用分析器,修改洩露的問題 避免循壞引用,dealloc rootviewcontroller block 的self 等引數 確定dealloc 方法按照預期呼叫了 基本上沒什麼好說了,你已經做了你該做的 顯然uikit本身還做了一些其它的你不需要知道的事情,也許是為了優化整個流程,也許是對特定的...

php fpm優化處理

php fpm.conf有兩個至關重要的引數 乙個是 max children 另乙個是 request terminate timeout 我的兩個設定的值乙個是 40 乙個是 900 但是這個值不是通用的,而是需要自己計算的。計算的方式如下 如 果你的伺服器效能足夠好,且寬頻資源足夠充足,php...