三、合適的(聯合)索引列順序
四、覆蓋索引和索引覆蓋
五、冗餘和重複索引
索引列不能是表示式的一部分,也不能是函式的引數。
對於blob、text或很長的varchar型別的列,必須使用字首索引,因為mysql不允許索引這些列的完整長度。
字首索引一般適用於 like '%'查詢,無法使用字首索引做order by和 group by,也無法*使用字首索引做覆蓋掃瞄。
使用欄位的一定字首長度構建索引。字首的「基數」應接近於完整列的「基數」,但又不能太長(為了節省空間),需要選擇合適的字首長度。實驗表明,字首長度為7時是最佳的。
【下面的例子是自己真實驗證】
有兩個表content_191008_test和content_191125_p 有資料量都在380萬左右,其中title
varchar(150)。這是乙個長的varchar型別列。
content_191008_test 建立乙個字首索引。另乙個表不建立索引。
alter table content_191008_test add key (title(7));
經驗法則:將選擇性最高的列放到索引最前列。
不需要考慮排序和分組時,將選擇性最高的列放在前面通常是很好的。
這部分主要講解如何建立聯合索引,按照「經驗法則」,那些「基數」越大的放在前面更好,但還是需要根據實際情況下來決定。
比如說userid、createtime兩個字段,createtime的基數一般來說比userid要大,但在實際情況下,createtime很多情況是進行範圍查詢,這樣就破壞了"聯合索引的最左原則",導致很多的查詢都受限不走索引。除非,多建立乙個索引,這樣在資料量很大的場景下,多乙個索引,在更新時會引起大量失效,造成額外的開支。
這裡只是舉個例子分析,那麼在具體應用場景中,還是根據業務場景來決定怎麼選擇聯合索引的列順序。
下面只是客觀的介紹怎麼計算「選擇性高」的方法。
如下面create_time、user_id、publish_time、status四個字段需要建立聯合索引,那麼下面分析來選擇合適的索引列順序。
content_191125_p表和content_191125_p1表,都有390萬的資料。利用公式計算如下:
基於上面的結果,對於兩個表分別建立索引
content_191125_p表索引是
content_191125_p1表索引是
建立索引後,實際查詢的結果如下:
[sql]
—按照上面的分析,明顯聯合索引比沒索引速度要快。
但並沒有驗證出「選擇性最高的列放到索引最前列」的效果在哪? --留著待後續再思考。
覆蓋索引:
select的資料列不必從資料表讀取,直接從二級索引中就可以取得。
乙個索引包含(或覆蓋)所有需要查詢的字段的值,稱為覆蓋索引。【索引的葉子節點已經包含要查詢的資料】
索引覆蓋:只通過索引,就能取到所需要的資料。
重複索引:相同的列上按照相同的順序建立的相同型別的索引。
冗餘索引:比如索引(a),又建立索引(a,b),那麼索引(a)冗餘了。
-------盡量避免處理冗餘和重複索引。
mysql高效能索引 mysql高效能索引( )
在開發中,我們知道大多數應用的瓶頸在於sql語句的執行時耗,在這裡並不討論sql語句的安全,僅僅討論高效能sql語句,而與高效能sql語句緊密相連的就是傳說中的 索引。索引 一種工作在儲存引擎端的用於快速找到記錄的一種資料結構。mysql使用索引的方式是 先找到索引的值,再根據索引的值找到資料行。索...
高效能的索引策略(上)
高效的選擇和使用索引有很多方式,其中有些事針對特殊案例的優化方法,有些則是針對特定行為的優化,使用哪個索引,以及如何評估選擇不同索引效能影響的技巧,則需要持續不斷的練習。接下來將介紹如何高效的使用索引。獨立的列 我們通常會看到一些查詢不當的使用索引,或者是的mysql無法使用已有的索引。如果查詢中的...
3 3 高效能的索引策略
在進行查詢時,索引列不能是表示式的一部分,也不能是函式的引數,否則無法使用索引。例如下面的查詢不能使用 actor id 列的索引 select actor id from sakila.actor where actor id 1 5 在需要使用多個列作為條件進行查詢時,使用多列索引比使用多個單列...