mysql數據庫索引


mysql數據庫索引
================================================================
mysql index 最左前綴原則查詢優化器

創建table示例
CREATE TABLE `index_test` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `a` int(11) DEFAULT NULL,
  `b` varchar(255) DEFAULT NULL,
  `c` int(11) DEFAULT NULL,
  `d` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `a_b_c` (`a`,`b`,`c`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

INSERT INTO `index_test` VALUES ('1', '1', 'b1', '3', '4');

sql驗證:
explain顯示MySQL如何使用索引來處理select語句以及連接表。
EXPLAIN
SELECT * from index_test WHERE a=1 and b='b1' AND c=3; -- key=a_b_c, key_len=268

EXPLAIN
SELECT * from index_test WHERE c=1 and b='b1' AND a=3; -- key=a_b_c, key_len=268

EXPLAIN
SELECT * from index_test WHERE a=1 and b='b1'; -- key=a_b_c, key_len=263

EXPLAIN
SELECT * from index_test WHERE a=1 and c=3; -- key=a_b_c, key_len=5

EXPLAIN
SELECT * from index_test WHERE b='b1' and c=3; -- key=, key_len=

EXPLAIN
SELECT * from index_test WHERE c=3 and b='b1'; -- key=, key_len=

EXPLAIN
SELECT * from index_test WHERE c=3 and a=1; -- key=a_b_c, key_len=5
1.mysql的查詢優化器會幫你優化成索引可以識別的形式,如a,b可以應用索引,b,a也是可以應用索引的;

2.最左前綴:顧名思義,就是最左優先,上例中我們創建了a_b_c多列索引,a爲最左,
如果使用了a,則會應用索引,可能只應用了a,也可能應用了a,b,如a,c只使用了a;ab則使用了a,b兩個,從key_len可以看出
如果沒有使用a(最左),則不會應用索引,如b,c;c,b

3.遇到範圍查詢(>、<、between、like)
like:
EXPLAIN
SELECT * from index_test WHERE a=1 and b like "%b%"; -- key=a_b_c, key_len=5(只a)
EXPLAIN
SELECT * from index_test WHERE a=1 and b like "b%"; -- key=a_b_c, key_len=263(a,b)
EXPLAIN
SELECT * from index_test WHERE a=1 and b like "%b%" AND c=3; -- key=a_b_c, key_len=5(只a,也沒應用c)
-- 如果LIKE的參數是一個不以通配符開頭的常量字符串,索引也可以用於LIKE比較。
-- like 'partten%';使用索引
-- like '%parrtn%'; 不使用索引
-------------------
=、>、>=
EXPLAIN
SELECT * from index_test WHERE a=1;    -- key=a_b_c, key_len=5
EXPLAIN
SELECT * from index_test WHERE a>1;    -- key=a_b_c, key_len=5
EXPLAIN
SELECT * from index_test WHERE a<1;    -- key=a_b_c, key_len=5
EXPLAIN
SELECT * from index_test WHERE a>=1;   -- key=, key_len=         沒使用index??TODO
EXPLAIN
SELECT * from index_test WHERE a<=1;   -- key=a_b_c, key_len=5

EXPLAIN
SELECT * from index_test WHERE a=1 and b="b1" AND c>=3; -- key=a_b_c, key_len=268 使用了index??TODO
-------------------
索引並不是時時都會生效的,比如以下幾種情況,將導致索引失效:
1.如果條件中有or,即使其中有條件帶索引也不會使用(這也是爲什麼儘量少用or的原因)
注意:要想使用or,又想讓索引生效,只能將or條件中的每個列都加上索引
2.對於多列索引,不是使用的第一部分,則不會使用索引
3.like查詢是以%開頭
4.如果列類型是字符串,那一定要在條件中將數據使用引號引用起來,否則不使用索引

5.如果mysql估計使用全表掃描要比使用索引快,則不使用索引(怎麼估計??)

(上面兩個TODO,怎麼估計,估計跟樹的開閉區間有關??)

此外,查看索引的使用情況
show status like ‘Handler_read%';
大家可以注意:
handler_read_key:這個值越高越好,越高表示使用索引查詢到的次數(??)

handler_read_rnd_next:這個值越高,說明查詢低效


==TODO====================================

EXPLAIN
SELECT * from index_test WHERE a=1 AND b like "b%" AND c=3; -- key=a_b_c, key_len=268
EXPLAIN
SELECT a,b,c from index_test WHERE a=1 AND b like "b%" AND c=3; -- key=a_b_c, key_len=5

EXPLAIN
SELECT * from index_test WHERE a=1 OR b = "b1"; -- key=, key_len=
EXPLAIN
SELECT a, b from index_test WHERE a=1 OR b = "b1"; -- key=a_b_c, key_len=268
======================================

B樹、B-樹、B+樹
生成
平衡(加減數據

發佈了80 篇原創文章 · 獲贊 40 · 訪問量 18萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章