MYSQL索引-單個索引和組合索引

新建一個test測試表

CREATE TABLE `test`  (
  `id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `username` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `age` int(11) NULL DEFAULT NULL,
  `address` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `sex` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE,
  INDEX `username、address組合`(`username`, `address`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;


INSERT INTO `test` VALUES ('1', 'jacklin', 23, '廣州', '1');
INSERT INTO `test` VALUES ('10', 'jacklin10', 23, '廣州2', '1');
INSERT INTO `test` VALUES ('11', 'jacklin11', 23, '廣州3', '1');
INSERT INTO `test` VALUES ('12', 'jacklin12', 23, '廣州4', '1');
INSERT INTO `test` VALUES ('13', 'jacklin13', 23, '廣州', '1');
INSERT INTO `test` VALUES ('2', 'jacklin2', 23, '廣州5', '1');
INSERT INTO `test` VALUES ('3', 'jacklin3', 23, '廣州6', '1');
INSERT INTO `test` VALUES ('4', 'jacklin4', 23, '廣州7', '1');
INSERT INTO `test` VALUES ('5', 'jacklin5', 23, '廣州8', '1');
INSERT INTO `test` VALUES ('6', 'jacklin6', 23, '廣州9', '1');
INSERT INTO `test` VALUES ('7', 'jacklin7', 23, '廣州10', '1');
INSERT INTO `test` VALUES ('8', 'jacklin8', 23, '廣州11', '1');
INSERT INTO `test` VALUES ('9', 'jacklin9', 23, '廣州12', '1');

單個索引

  1. 當不加索引時

首先在“username”和“address”這倆字段不加索引的情況下執行一個查詢語句,並分析

​​​​​​​SELECT * FROM test WHERE `username` = 'jacklin';
SELECT * FROM test WHERE `address` = '廣州';

可以看到兩天查詢語句都沒有走索引,總共查詢13條數據,而表中也是一共13條數據,相當於全表掃描了。

新增“username”、“address“單列索引

alter table test add index `idx_username` (`username`);
alter table test add index `idx_address` (`address`);

再執行explain解析命令查看結果:

可以看到:加上索引後,單列查詢是可以走索引的,對應的掃描的行數也變成1和2。

接下來我們看兩個條件一起查詢,使用and和or條件測試:

SELECT * FROM test WHERE `username` = 'jacklin' and `address` = '廣州';

可以看到:加上索引後and查詢是可以走索引的,但是隻有一個索引起作用,對於另一個索引字段還是要進行遍歷,而且and查詢會根據關聯性高(符合該條件的行數少)選擇具體走哪個索引

SELECT * FROM test WHERE username = 'jacklin' or address = '廣州';

可以發現,or查詢也是走索引的,但是看到一些說不走索引,我自己親測是走的!

組合索引

刪除原先的單列索引,新增組合索引

alter table test drop index `idx_username`
alter table test drop index `idx_address`

新增組合索引

alter table test add index `idx_username_address_combination` (`username`,`address`);

執行單列查詢語句

​​​​​​​SELECT * FROM test WHERE `username` = 'jacklin';
SELECT * FROM test WHERE `address` = '廣州';

發現根據username查詢時,有走聯合索引,但是根據address查詢的時候沒有走索引,而是全表掃描了,證明了組合索引符合“最左原則”,意思是組合索引 (`username`, `address`) 相當於新建了 `username` 和 (`username`, `address`) 兩種索引,並未建 `address` 索引,這個一定要弄清楚!

如果組合索引是(A,B),則對於條件A=a,是可以用上這個組合索引的,因爲組合索引是先按照第一列進行排序的,所以沒必要對A單獨建立一個索引,但是對於B=b就用不上了,因爲只有在第一列相同的情況下,才比較第二列,因而第二列相同的,可以分佈在不同的節點上,沒辦法快速定位 ​​​​​​​

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章