資料庫查詢和資料庫(MySQL)索引的最佳化建議

新夢想IT發表於2019-08-21

索引是幫助MySQL高效獲取資料的資料結構,在儲存引擎中實現的,所以每種儲存引擎中的索引都不一樣。那麼,資料庫中的索引有什麼作用?引入索引的目的是為了加快查詢速度。如果資料量很大,大的查詢要從硬碟載入資料到記憶體當中。

一、資料庫查詢效能的最佳化涉及到的技術面非常廣,一般建議用以下幾個手段實行:

1、減少資料訪問

相關的技術就是建立合適的索引,將全表掃描、索引掃描(scan)等耗時的操作轉化為索引查詢(seek)。建立正確的索引,能讓資料庫查詢效能提升100-1000倍甚至更高,就好比一本非常厚的詞典,如果沒有任何索引,你要查一個東西,那可是相當費盡,需要整本書查一遍,有索引就可以直接根據索引定位了。這是最重要的改善效能的途徑。

2、減少返回的資料

在網路中傳輸資料,頻寬是有限的,如果能按需提取最少量的資料,會起到不錯的作用。這裡需要注意的是,在SQL中,不要出現select *,而是需要什麼欄位,就提取什麼欄位。

資料庫查詢和資料庫(MySQL)索引的最佳化建議

3、減少與資料庫互動次數

網路資源有限,顯然,頻繁與資料庫互動,也是制約效能的一個因素。一個良好的建議就是,使用儲存過程,或者批處理語句,這樣能減少與資料庫的互動,提升一部分效能。

4、減少CPU的負荷

這裡,主要是使用快取計劃。在查詢中,儘量使用引數化的查詢。這樣的話,資料庫會對查詢引數進行快取,從而複用查詢計劃。

5、提升硬體效能

這是最後一招了,如果其他方面都已經做得非常不錯了,效能瓶頸在CPU,記憶體和磁碟上,那採取提升硬體效能的方案就會顯得比較合適了,否則還是先去最佳化其他的地方吧。

以上5個層次的最佳化帶來的效能改善,是依次下降的,是一個倒置的金字塔。

二、下面說一下索引以及最佳化建議

索引能大幅度提高查詢和排序效能,但是,在插入、刪除、以及修改了主鍵的操作中,是需要維護索引順序的。如果一張頻繁變更的表,是不宜建立過多的索引的,索引帶來的負面效能影響,將會得不償失。

索引最佳化,是一個很考究的事情,它需要找到一個平衡點。

MySQL的最佳化主要分為結構最佳化(Scheme optimization)和查詢最佳化(Query optimization)。本章討論的高效能索引策略主要屬於結構最佳化範疇。本章的內容完全基於上文的理論基礎,實際上一旦理解了索引背後的機制,那麼選擇高效能的策略就變成了純粹的推理,並且可以理解這些策略背後的邏輯。

索引最佳化建議

1、字首索引

字首索引就是用列的字首代替整個列作為索引key,當字首長度合適時,可以做到既使得字首索引的選擇性接近全列索引,同時因為索引key變短而減少了索引檔案的大小和維護開銷。

一般來說以下情況可以使用字首索引:

字串列(varchar,char,text等),需要進行全欄位匹配或者前匹配。也就是=‘xxx’ 或者 like ‘xxx%’

字串本身可能比較長,而且前幾個字元就開始不相同。比如我們對中國人的姓名使用字首索引就沒啥意義,因為中國人名字都很短,另外對收件地址使用字首索引也不是很實用,因為一方面收件地址一般都是以XX省開頭,也就是說前幾個字元都是差不多的,而且收件地址進行檢索一般都是like ’%xxx%’,不會用到前匹配。相反對外國人的姓名可以使用字首索引,因為其字元較長,而且前幾個字元的選擇性比較高。同樣電子郵件也是一個可以使用字首索引的欄位。

資料庫查詢和資料庫(MySQL)索引的最佳化建議

前一半字元的索引選擇性就已經接近於全欄位的索引選擇性。如果整個欄位的長度為20,索引選擇性為0.9,而我們對前10個字元建立字首索引其選擇性也只有0.5,那麼我們需要繼續加大字首字元的長度,但是這個時候字首索引的優勢已經不明顯,沒有太大的建字首索引的必要了。

2、主鍵外檢一定要建索引。

3、對 where,on,group by,order by 中出現的列使用索引。

4、儘量選擇區分度高的列作為索引,區分度的公式是count(distinct col)/count(*),表示欄位不重複的比例,比例越大我們掃描的記錄數越少,唯一鍵的區分度是1,而一些狀態、性別欄位可能在大資料面前區分度就是0。

5、對較小的資料列使用索引,這樣會使索引檔案更小,同時記憶體中也可以裝載更多的索引鍵。

6、索引列不能參與計算,保持列“乾淨”,比如from_unixtime(create_time) = ’2014-05-29’就不能使用到索引,原因很簡單,b+樹中存的都是資料表中的欄位值,但進行檢索時,需要把所有元素都應用函式才能比較,顯然成本太大。所以語句應該寫成create_time = unix_timestamp(’2014-05-29’)。

7、為較長的字串使用字首索引。

8、儘量的擴充套件索引,不要新建索引。比如表中已經有a的索引,現在要加(a,b)的索引,那麼只需要修改原來的索引即可。

9、不要過多建立索引, 權衡索引個數與DML之間關係,DML也就是插入、刪除資料操作。這裡需要權衡一個問題,建立索引的目的是為了提高查詢效率的,但建立的索引過多,會影響插入、刪除資料的速度,因為我們修改的表資料,索引也需要進行調整重建。

10、對於like查詢,”%”不要放在前面。

SELECT * FROMhoudunwangWHEREunameLIKE'後盾%' -- 走索引。

SELECT * FROMhoudunwangWHEREunameLIKE "%後盾%" -- 不走索引。

11、查詢where條件資料型別不匹配也無法使用索引。

字串與數字比較不使用索引;

CREATE TABLEa(achar(10))。

EXPLAIN SELECT * FROMaWHEREa="1" – 走索引。

EXPLAIN SELECT * FROM a WHERE a=1 – 不走索引。

正規表示式不使用索引,這應該很好理解,所以為什麼在SQL中很難看到regexp關鍵字的原因。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69940641/viewspace-2654475/,如需轉載,請註明出處,否則將追究法律責任。

相關文章