1. 程式人生 > >8.MySQL8.0索引條件下推優化(ICP)

8.MySQL8.0索引條件下推優化(ICP)

介紹

索引條件下推(ICP)是對MySQL使用索引從表中檢索行的情況的優化。 如果沒有ICP,儲存引擎會遍歷索引以查詢基表中的行,並將它們返回給MySQL伺服器,該伺服器會評估行的WHERE條件。 啟用ICP後,如果只使用索引中的列來評估WHERE條件的某些部分,MySQL伺服器會將WHERE條件的這一部分推送到儲存引擎。 然後,儲存引擎通過使用索引條目來評估推送的索引條件,並且僅當滿足該條件時才從表中讀取行。 ICP可以減少儲存引擎必須訪問基表的次數以及MySQL伺服器必須訪問儲存引擎的次數。

講解

Index Condition Pushdown適用於以下情況:

  • 當進行全表訪問時,ICP用於range,ref,eq_ref和ref_or_null訪問方法。
  • ICP可用於InnoDB和MyISAM表,包括分割槽的InnoDB和MyISAM表。
  • 對於InnoDB表,ICP僅用於二級索引。 ICP的目標是減少全行讀取的數量,從而減少I/O操作。 對於InnoDB聚簇索引,完整記錄已經讀入InnoDB緩衝區。 在這種情況下使用ICP不會降低I/O.
  • 在虛擬生成列上建立的二級索引不支援ICP。 InnoDB支援虛擬生成列的二級索引。
  • 引用子查詢的條件無法下推。
  • 引用儲存過程的條件無法下推。 儲存引擎無法呼叫儲存過程。
  • 觸發器也無法執行此優化。

下面解釋一下不使用ICP技術時,索引掃描方式:

  • 獲取下一行,首先讀取索引元組,然後使用索引元組找到並讀取整個錶行。
  • 然後根據Where條件判斷這行是否滿足條件,根據結果判斷是否保留該行

在使用索引條件下推之後,索引掃描方式改為如下模式:

  • 獲取下一行的索引元組(但不是完整的錶行)。
  • 測試適用於此表的WHERE條件的一部分,並且只能使用索引列進行檢查。 如果不滿足條件,則繼續下一行的索引元組。
  • 如果滿足條件,請使用索引元組來查詢並讀取整個錶行。
  • 測試Where條件的其他部分,根據結果判斷是否保留該行。

EXPLAIN輸出顯示使用索引條件下推時在Extra列中使用索引條件。 它不顯示使用索引,因為在必須讀取完整的錶行時不適用。

例如:

假設一個表包含有關人員及其地址的資訊,並且該表的索引定義為INDEX(zipcode,lastname,firstname)。 如果我們知道一個人的郵政編碼值但不確定姓氏,我們可以像這樣搜尋:

SELECT * FROM people
WHERE zipcode='95054'
AND lastname LIKE '%etrunia%'
AND address LIKE '%Main Street%';

MySQL可以使用索引來掃描zipcode =‘95054’的人。 第二部分(姓氏LIKE’%etrunia%’)不能用於限制必須掃描的行數,因此如果沒有Index Condition Pushdown,此查詢必須為所有擁有zipcode ='95054’的人檢索完整的錶行。

當使用ICP時,MySQL在讀取整個錶行之前先檢索lastname LIKE ‘%etrunia%’,它使用索引避免了讀取滿足zipcode='95054’的條件但是不滿足lastname LIKE '%etrunia%'的條件的錶行。

此功能在MySQL8.0中預設開啟,如需關閉使用如下語句

SET optimizer_switch = 'index_condition_pushdown=off';
SET optimizer_switch = 'index_condition_pushdown=on';