Mysql Index extends最佳化

來源:互聯網
上載者:User

標籤:

  Innodb通過自動把主鍵列添加到每個二級索引來擴充它們:

 

CREATE TABLE t1 (  i1 INT NOT NULL DEFAULT 0,  i2 INT NOT NULL DEFAULT 0,  d DATE DEFAULT NULL,  PRIMARY KEY (i1, i2),  INDEX k_d (d)) ENGINE = InnoDB;

 

   該表定義(t1,t2)為聯合主鍵,也定義個二級索引k_id 在列(d)上,但是內部innodb會擴充它,變成列index(d,i1,i2);

 

   版本5.6.9之前,最佳化器不會這麼最佳化,但在5.6.9,開始支援,可以得到更好的效能和更有效執行計畫;

   最佳化器可以用擴充的二級索引來進行ref,range,index_merge等類型index access,鬆散的index sacns,join串連和排序最佳化,和min()/max()最佳化;

   資料:

INSERT INTO t1 VALUES(1, 1, ‘1998-01-01‘), (1, 2, ‘1999-01-01‘),(1, 3, ‘2000-01-01‘), (1, 4, ‘2001-01-01‘),(1, 5, ‘2002-01-01‘), (2, 1, ‘1998-01-01‘),(2, 2, ‘1999-01-01‘), (2, 3, ‘2000-01-01‘),(2, 4, ‘2001-01-01‘), (2, 5, ‘2002-01-01‘),(3, 1, ‘1998-01-01‘), (3, 2, ‘1999-01-01‘),(3, 3, ‘2000-01-01‘), (3, 4, ‘2001-01-01‘),(3, 5, ‘2002-01-01‘), (4, 1, ‘1998-01-01‘),(4, 2, ‘1999-01-01‘), (4, 3, ‘2000-01-01‘),(4, 4, ‘2001-01-01‘), (4, 5, ‘2002-01-01‘),(5, 1, ‘1998-01-01‘), (5, 2, ‘1999-01-01‘),(5, 3, ‘2000-01-01‘), (5, 4, ‘2001-01-01‘),(5, 5, ‘2002-01-01‘);

查詢sql:

EXPLAIN SELECT COUNT(*) FROM t1 WHERE i1 = 3 AND d = ‘2000-01-01‘;

    這種情況下,最佳化器不會使用主鍵,因為主鍵有(t1,t2)組成,但是該查詢中沒有引用i2;最佳化器會選擇二級索引 k_d(d) ,執行計畫依賴與是否擴充index被使用;

    當最佳化器沒有使用index extensions時,他對待 k_d 僅僅為(d).

mysql> EXPLAIN SELECT COUNT(*) FROM t1 WHERE i1 = 3 AND d = ‘2000-01-01‘\G*************************** 1. row ***************************           id: 1  select_type: SIMPLE        table: t1         type: refpossible_keys: PRIMARY,k_d          key: k_d      key_len: 4          ref: const         rows: 5        Extra: Using where; Using index

當最佳化器把index extensions考慮在內的話,對待k_d (d,i1,i2), 這種情況下,他可以使用最左首碼(d,i1)開得到一個更好的執行計畫;

mysql> EXPLAIN SELECT COUNT(*) FROM t1 WHERE i1 = 3 AND d = ‘2000-01-01‘\G*************************** 1. row ***************************           id: 1  select_type: SIMPLE        table: t1         type: refpossible_keys: PRIMARY,k_d          key: k_d      key_len: 8          ref: const,const         rows: 1        Extra: Using index

兩種情況下,key列顯示最佳化器都會選擇用二級索引k-d,但是 :

    1:key_len列從4bytes 變成了8 bytes,說明了key 是尋找的 列 d 和 i1,而不是僅僅d;

    2: rows列計數從5減少到1,說明 innodb檢測更少的行來得到結構;

    3:Extra列從 using where;using index 變成了using index,意味著結果只使用了index,沒有access資料行;

 

最佳化器使用擴充的Index行為不同也可以通過show status指令來觀看:

FLUSH TABLE t1;FLUSH STATUS;SELECT COUNT(*) FROM t1 WHERE i1 = 3 AND d = ‘2000-01-01‘;SHOW STATUS LIKE ‘handler_read%‘

flush table :清除Table cache;

flush status:清除狀態計數;

沒有index extendsions,show status:

+-----------------------+-------+| Variable_name         | Value |+-----------------------+-------+| Handler_read_first    | 0     || Handler_read_key      | 1     || Handler_read_last     | 0     || Handler_read_next     | 5     || Handler_read_prev     | 0     || Handler_read_rnd      | 0     || Handler_read_rnd_next | 0     |+-----------------------+-------+

有index extensions,show status: handler_read_next 從5變成1

+-----------------------+-------+| Variable_name         | Value |+-----------------------+-------+| Handler_read_first    | 0     || Handler_read_key      | 1     || Handler_read_last     | 0     || Handler_read_next     | 1     || Handler_read_prev     | 0     || Handler_read_rnd      | 0     || Handler_read_rnd_next | 0     |+-----------------------+-------+

optimizer_switch系統變數的use_index_extensions標誌可以控制是否最佳化器進行二級索引擴充,預設,是開啟的,
SET optimizer_switch = ‘use_index_extensions=off‘;

Mysql Index extends最佳化

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.