mysql 不排序 MySQL高效索引 覆蓋索引

2021-10-12 20:12:10 字數 2827 閱讀 1198

概念如果索引包含所有滿足查詢需要的資料,則該索引稱為覆蓋索引(covering index),也就是平時所說的不需要回表操作。

判斷標準

使用explain,可以通過輸出的extra列來判斷,對於乙個索引覆蓋查詢,顯示為using index,mysql查詢優化器在執行查詢前會決定是否有索引覆蓋查詢

注意

1、覆蓋索引也並不適用於任意的索引型別,索引必須儲存列的值

2、hash 和full-text索引不儲存值,因此mysql只能使用b-tree

3、並且不同的儲存引擎實現覆蓋索引都是不同的

4、並不是所有的儲存引擎都支援它們

5、如果要使用覆蓋索引,一定要注意select 列表值取出需要的列,不可以是select *,因為如果將所有字段一起做索引會導致索引檔案過大,查詢效能下降,不能為了利用覆蓋索引而這麼做

innodb

1、覆蓋索引查詢時除了索引本身的包含的列,還可以使用其預設的聚集索引列

2、這跟innob的索引結構有關係,主索引是b+樹索引儲存,也即我們所說的資料行即索引,索引即資料

3、對於innodb的輔助索引,它的葉子節點儲存的是索引值和指向主鍵索引的位置,然後需要通過主鍵在查詢表的字段值,所以輔助索引儲存了主鍵的值

4、覆蓋索引也可以用上innodb 預設的聚集索引

5、innodb引擎的所有儲存了主鍵id,事務id,回滾指標,非主鍵id,他的查詢就會是非主鍵id也可覆蓋來取得主鍵id

覆蓋索引是一種非常強大的工具,能大大提高查詢效能,只需要讀取索引而不用讀取資料有以下一些優點

1、索引項通常比記錄要小,所以mysql訪問更少的資料

2、索引都按值的大小順序儲存,相對於隨機訪問記錄,需要更少的i/o

3、大多數據引擎能更好的快取索引,比如myisam只快取索引

4、覆蓋索引對於innodb表尤其有用,因為innodb使用聚集索引組織資料,如果二級索引中包含查詢所需的資料,就不再需要在聚集索引中查詢了

在sakila的inventory表中,有乙個組合索引(store_id,film_id),對於只需要訪問這兩列的查 詢,mysql就可以使用索引,如下

表結構

在大多數引擎中,只有當查詢語句所訪問的列是索引的一部分時,索引才會覆蓋。但是,innodb不限於此,innodb的二級索引在葉子節點中儲存了 primary key的值。

因此,sakila.actor表使用innodb,而且對於是last_name上有索引,所以,索引能覆蓋那些訪問actor_id的查 詢,如下

使用索引進行排序

mysql中,有兩種方式生成有序結果集:一是使用filesort,二是按索引順序掃瞄

利用索引進行排序操作是非常快的,而且可以利用同一索引同時進 行查詢和排序操作。當索引的順序與order by中的列順序相同且所有的列是同一方向(全部公升序或者全部降序)時,可以使用索引來排序,如果查詢是連線多個表,僅當order by中的所有列都是第乙個表的列時才會使用索引,其它情況都會使用filesort

當mysql不能使用索引進行排序時,就會利用自己的排序演算法(快速排序演算法)在記憶體(sort buffer)中對資料進行排序,如果記憶體裝載不下,它會將磁碟上的資料進行分塊,再對各個資料塊進行排序,然後將各個塊合併成有序的結果集(實際上就是外排序)

對於filesort,mysql有兩種排序演算法

1、兩遍掃瞄演算法(two passes)

實現方式是先將需要排序的字段和可以直接定位到相關行資料的指標資訊取出,然後在設定的記憶體(通過引數sort_buffer_size設定)中進行排序,完成排序之後再次通過行指標資訊取出所需的columns

注:該演算法是4.1之前採用的演算法,它需要兩次訪問資料,尤其是第二次讀取操作會導致大量的隨機i/o操作。另一方面,記憶體開銷較小

2、 一次掃瞄演算法(single pass)該演算法一次性將所需的columns全部取出,在記憶體中排序後直接將結果輸出

注:從 mysql 4.1 版本開始使用該演算法。它減少了i/o的次數,效率較高,但是記憶體開銷也較大。如果我們將並不需要的columns也取出來,就會極大地浪費排序過程所需要 的記憶體。在 mysql 4.1 之後的版本中,可以通過設定 max_length_for_sort_data 引數來控制 mysql 選擇第一種排序演算法還是第二種。當取出的所有大字段總大小大於 max_length_for_sort_data 的設定時,mysql 就會選擇使用第一種排序演算法,反之,則會選擇第二種。為了盡可能地提高排序效能,我們自然更希望使用第二種排序演算法,所以在 query 中僅僅取出需要的 columns 是非常有必要的。

當對連線操作進行排序時,如果order by僅僅引用第乙個表的列,mysql對該錶進行filesort操作,然後進行連線處理,此時,explain輸出「using filesort」;否則,mysql必須將查詢的結果集生成乙個臨時表,在連線完成之後進行filesort操作,此時,explain輸出 「using temporary;using filesort」

mysql建立高效索引 mysql建立高效索引分析

一 如何建立理想的索引?查詢頻繁度 區分度索引長度 覆蓋字段 1.1區分度 假設100萬使用者,性別基本上男 女各為50w,區分度就低。1.2長度小 索引長度直接影響索引檔案的大小,影響增刪改的速度,並間接影響查詢速度 占用記憶體多 1.3區分度高,長度小 如何讓區分度高,而長度小?可以針對列中的值...

Mysql高效分頁

通常針對mysql大資料量的查詢採取 分頁 策略,但是如果翻頁到比較靠後的位置時查詢將變得很慢,因為mysql將花費大量的時間來掃瞄需要丟棄的資料。通常情況下,為了實現高效分頁,需要在查詢中where條件列和排序列應用組合索引。例如,建立索引 a,b,c 使得以下查詢可以使用索引,提高查詢效率 1 ...

mysql 連線不上 mysql連線不上怎麼辦

下面是mysql的連線方式 使用mysql二進位制方式連線 您可以使用mysql二進位制方式進入到mysql命令提示符下來連線mysql資料庫。例如以下是從命令列中連線mysql伺服器的簡單例項 root host mysql u root p enter password 在登入成功後會出現 my...