常見的MySQL優化方案1

前言:我們先了解一下sql性能優化

性能優化(Optimize)指的是在保證系統正確性的前提下,能夠更快速響應請求的一種手段。而且有些性能問題,比如慢查詢等,如果積累到一定的程度或者是遇到急速上升的併發請求之後,會導致嚴重的後果,輕則造成服務繁忙,重則導致應用不可用。它對我們來說就像一顆即將被引爆的定時炸彈一樣,時刻威脅着我們。因此在上線項目之前需要嚴格的把關,以確保 MySQL 能夠以最優的狀態進行運行。

MySQL 的優化方案有哪些?

MySQL 數據庫常見的優化手段分爲三個層面:SQL 和索引優化、數據庫結構優化、系統硬件優化等,然而每個大的方向中又包含多個小的優化點,下面我們具體來看看。

優化注意事項:

依據數據而不是憑空猜測

忌過早優化

忌過度優化

深入理解業務

性能優化是持久戰

選擇合適的衡量指標、測試用例、測試環境

優化目標

(1)減少 IO 次數

IO永遠是數據庫最容易瓶頸的地方,這是由數據庫的職責所決定的,大部分數據庫操作中超過90%的時間都是 IO 操作所佔用的,減少 IO 次數是 SQL 優化中需要第一優先考慮,當然,也是收效最明顯的優化手段。

(2)降低 CPU 計算
除了 IO 瓶頸之外,SQL優化中需要考慮的就是 CPU 運算量的優化了。order by, group by,distinct … 都是消耗 CPU 的大戶(這些操作基本上都是 CPU 處理內存中的數據比較運算)。當我們的 IO 優化做到一定階段之後,降低 CPU 計算也就成爲了我們 SQL 優化的重要目標

優化方案1: SQL 和索引優化

(1)使用正確的索引

索引是數據庫中最重要的概念之一,也是提高數據庫性能最有效的手段之一,它的誕生本身就是爲了提高數據查詢效率的,就像字典的目錄一樣,通過目錄可以很快找到相關的內容。我們應該儘可能的使用主鍵查詢,而非其他索引查詢,因爲主鍵查詢不會觸發回表查詢,因此節省了一部分時間,變相的提高了查詢的性能。

索引類型:普通索引、主鍵索引、唯一索引、組合索引、全文索引

假如我們沒有添加索引,那麼在查詢時就會觸發全表掃描,因此查詢的數據就會很多,並且查詢效率會很低,爲了提高查詢的性能,我們就需要給最常使用的查詢字段上,添加相應的索引,這樣才能提高查詢的性能

(2)sql書寫時的注意

在 MySQL 5.0 之前的版本要儘量避免使用 or 查詢

可以使用 union 或者子查詢來替代,因爲早期的 MySQL 版本使用 or 查詢可能會導致索引失效,在 MySQL 5.0 之後的版本中引入了索引合併,簡單來說就是把多條件查詢,比如 or 或 and 查詢的結果集進行合併交集或並集的功能,因此就不會導致索引失效的問題了。如果限制條件中其他字段沒有索引,儘量少用or。
避免在 where 查詢條件中使用 != 或者 <> 操作符,因爲這些操作符會導致查詢引擎放棄索引而進行全表掃描。

適當使用前綴索引
MySQL 是支持前綴索引的,也就是說我們可以定義字符串的一部分來作爲索引。我們知道索引越長佔用的磁盤空間就越大,那麼在相同數據頁中能放下的索引值也就越少,這就意味着搜索索引需要的查詢時間也就越長,進而查詢的效率就會降低,所以我們可以適當的選擇使用前綴索引,以減少空間的佔用和提高查詢效率。
要儘量避免使用 select *,而是查詢需要的字段,這樣可以提升速度,以及減少網絡傳輸的帶寬壓力。

關於JOIN優化
儘量使用 Join 語句來替代子查詢,因爲子查詢是嵌套查詢,而嵌套查詢會新創建一張臨時表,而臨時表的創建與銷燬會佔用一定的系統資源以及花費一定的時間,但 Join 語句並不會創建臨時表,因此性能會更高。

我們要儘量使用小表驅動大表的方式進行查詢

也就是如果 B 表的數據小於 A 表的數據,那執行的順序就是先查 B 表再查 A 表。
不要在列字段上進行算術運算或其他表達式運算,否則可能會導致查詢引擎無法正確使用索引,從而影響了查詢的效率。

增加冗餘字段可以減少大量的連表查詢

因爲多張表的連表查詢性能很低,所有可以適當的增加冗餘字段,以減少多張表的關聯查詢,這是以空間換時間的優化策略。
避免類型轉換,這裏所說的“類型轉換”是指 where 子句中出現 column 字段的類型和傳入的參數類型不一致的時候發生的類型轉換。

儘量用 union all 代替 union

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

儘量少排序 order by

排序操作會消耗較多的 CPU 資源,所以減少排序可以在緩存命中率高等 IO 能力足夠的場景下會較大影響 SQL 的響應時間。如果排序字段沒有用到索引,就儘量少排序。

SQL語句中IN包含的值不應過多

MySQL對於IN做了相應的優化,即將IN中的常量全部存儲在一個數組裏面,而且這個數組是排好序的。但是如果數值較多,產生的消耗也是比較大的。

當只需要一條數據的時候,使用limit 1,這是爲了使EXPLAIN中type列達到const類型。
區分in和exists, not in和not exists。
使用合理的分頁方式以提高分頁的效率。

分段查詢
避免在 where 子句中對字段進行 null 值判斷
不建議使用%前綴模糊查詢,如果使用%前綴來模糊查詢,建議使用全文索引。

對於聯合索引來說,要遵守最左前綴法則
比如:組合索引(a,b,c)三列,我們可以使用(a)、(a,b)、(a,c)、(b、c)、(a,b,c)但是不能以(b,a)、(c,a)、(c,b)等組合使用否則導致索引失效。
必要時可以使用force index來強制查詢走某個索引。

文章最後:

以上這些優化方案我們都可以通過 慢查詢機制 EXPLAIN方式來驗證。

在這裏插入圖片描述
EXPLAIN各個字段詳介紹:

在這裏插入圖片描述

type字段值如下:

在這裏插入圖片描述

在這裏插入圖片描述

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