前綴索引和索引選擇性
有時候需要索引很長的字符,這會讓索引變得大且慢,一個策略是模擬哈希索引,
通常可以索引開始的部分字符,這樣可以大大解約索引空間,提高索引效率,但這樣會降低索引的選擇性,
索引的選擇性:不重復的索引值(也成為基數)和資料表的記錄總數比值,索引的選擇性越高則查詢效率越高,因為選擇性高的索引可以在查找時過濾更多的行,唯一索引的選擇性為1,是選擇性最好的,
前綴索引是一種能使索引更小更快的辦法,但也有缺點:
MySQL無法使用ORDER BY和GROUP BY,也無法使用覆寫掃描,
聚簇索引
聚簇索引并不是一種單獨的索引型別,是一種資料存盤方式,
當表有聚簇索引時,它的資料行實際上存放在索引的葉子頁,
聚簇:資料行和相鄰的鍵值緊湊的存盤在一起,
如果沒有定義主鍵,InnoDB會選擇一個唯一的非空索引代替,
如果沒有這樣的索引,會隱式定義一個主鍵作為聚簇索引,
聚簇索引的缺點
-
插入速度嚴重依賴插入順序,按照主鍵的順序插入是加載資料到InnoDB表中速度最快的方式,但如果不是按照主鍵順序加載資料,最好使用OPYIMIZE TABLE重新組織表,
-
基于聚簇索引的表在插入新行,或者主鍵被遷移時,可能會“頁分裂”,當行的主鍵值要求必須將這一行插入到某個已滿的頁中時,存盤引擎會將該頁分裂成兩個頁面來容納該行,這是一次頁分裂操作,頁分裂會導致表占用更多的磁盤空間,
覆寫索引
通常大家會根據查詢的WHERE條件創建合適的索引,設計優秀的索引也可以使用索引來直接獲取列的資料,
如果索引的葉子結點已經包含要查詢的資料,那還要什么必要再回表查詢呢?如果一個索引包含所有需要查詢的欄位的值,我們稱之為“覆寫索引”,

延遲關聯
使用inner join做子查詢,在查詢的第一個階段可以使用覆寫索引,雖然無法使用索引覆寫整個查詢,但比完全無法利用索引覆寫的好,
冗余和重復索引
索引越大越多,插入資料越慢,
可以使用Percona Toolkit中的pt-duplicate-key-checker分析表結構找出冗余的索引,
單表建多少個索引才合適?
大表,主鍵有一個唯一索引,再有一到兩個組合索引,最多三個索引足夠用了,
索引數量不能超過4個/表,
一切服從應用需要,在一張表上創建多少索引,創建什么樣的索引,并無一定之規,不能說一張表上有了 7個索引,就不能再創建第 8個索引了,
索引的多少取決于具體的業務場景,
在oltp中,表經常需要insert等,那么索引不能過多,一般超過3個就會對性能有影響,
在olap中如果表只是用于查詢,那么建多個索引也無妨,
索引和鎖
索引可以讓查詢鎖定更少的行,但是,如果索引無法過濾掉無效的行,那么在InnoDB檢索到資料并回傳給服務器層以后,MySQL才能用那個用WHERE子句,這時已經無法避免鎖定行了:InnoDB已經鎖定了這些行,
mysql> select actor_id from sakila.actor where actor_id < 5 and actor_id <> 1 for update;
雖然這條查詢回傳的是2,3,4,但是實際上獲取了1-4的排他鎖,
話句話說,存盤引擎的操作是“找小于5的記錄”,服務器并沒有告訴InnoDB可以過濾第1行的WHERE條件,注意到EXPLAIN的Extra列出現了“Using where”,這表示MySQL將存盤引擎回傳行以后再應用WHERE過濾條件,
using where 代表MYSQL服務器層在存盤引擎層回傳行以后再應用WHERE過濾條件
查詢性能優化
對于性能低下的查詢,通過兩個步驟來分析非常有效:
1、確認應用程式是否在檢索大量超過需要的資料,這意味著訪問了過多的行或者是過多的列,
2、確認MySQL服務器層是否在分析大量超過需要的資料行,
-
比如使用 * 來回傳全部列,其實有些列是用不到的,應該精簡,或者說重復查詢相同改的資料,這應該把這種資料放到快取里,下次查先從快取取,熱點資料每次取可以給加過期時間,
-
確認EXPLAIN中掃描的行數和訪問型別
在EXPLAIN中的type列是訪問型別,從全表掃描、索引掃描、范圍掃描、唯一索引查詢、常數參考(全索范唯),他們的查詢速度是從慢到快,
Re
《高性能MySQL》
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/308479.html
標籤:MySQL
上一篇:通過Python收集MySQL MHA 部署及運行狀態資訊的功能實作
下一篇:MySQL45講之IO性能提升
