效能優化(optimize)指的是在保證系統正確性的前提下,能夠更快速響應請求的一種手段。而且有些效能問題,比如慢查詢等,如果積累到一定的程度或者是遇到急速上公升的併發請求之後,會導致嚴重的後果,輕則造成服務繁忙,重則導致應用不可用。它對我們來說就像一顆即將被引爆的定時炸彈一樣,時刻威脅著我們。因此在上線專案之前需要嚴格的把關,以確保 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)使用正確的索引
索引是資料庫中最重要的概念之一,也是提高資料庫效能最有效的手段之一,它的誕生本身就是為了提高資料查詢效率的,就像字典的目錄一樣,通過目錄可以很快找到相關的內容。我們應該盡可能的使用主鍵查詢,而非其他索引查詢,因為主鍵查詢不會觸發回表查詢,因此節省了一部分時間,變相的提高了查詢的效能。
索引型別:普通索引、主鍵索引、唯一索引、組合索引、全文索引假如我們沒有新增索引,那麼在查詢時就會觸發全表掃瞄,因此查詢的資料就會很多,並且查詢效率會很低,為了提高查詢的效能,我們就需要給最常使用的查詢欄位上,新增相應的索引,這樣才能提高查詢的效能
(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字段值如下:
Mysql的優化方案
1 避免放棄使用索引而進行全表掃瞄的情況 在where後的條件中盡量不使用 2 正確的使用索引 3 正確選擇exist 與 in 和 not exist 與 not in 在任何情況下 not exist 的效率都高於 not in 4 使用join來替代子查詢 子查詢 通過select語句來建立乙...
Mysql優化方案
client 客戶端編碼方式,最好和服務端儲存一致 loose default character set utf8 mysqld 埠port 3306 mysql根目錄 basedir d ide mysql 5.6.25 winx64 資料檔案存放目錄 datadir d ide mysql 5...
MySQL優化方案
select 和select 欄位的優化。我們先測試一下,我的測試資料庫裡有26萬條記錄。再查詢一下列數 select count from information schema.columns where table schema lezhi data and table name demo jo...