1、建表語句如下所示:
DROP TABLE IF EXISTS `p_user`;
CREATE TABLE `p_user` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(10) default NULL,
`sex` char(2) default NULL,
PRIMARY KEY (`id`)
);
INSERT INTO `p_user` VALUES (‘1’, ‘A’, ‘男’);
INSERT INTO `p_user` VALUES (‘2’, ‘B’, ‘女’);
INSERT INTO `p_user` VALUES (‘3’, ‘C’, ‘男’);

然后給name字段創建Unique索引,請自行百度。
explain函數驗證索引是否有效
第一步:使用列表name查詢驗證索引。
1、使用索引列時索引才會生效,語句如下:
explain select * from p_user WHERE name=’B’

2、不使用索引查詢:
explain select * from p_user

第二步:失效的索引。
1、使用語句:
explain select * from p_user WHERE name != ‘A’
第三步:復合場景。
1、使用語句:
explain select * from p_user WHERE name=’B’ AND name != ‘A’


explain函數介紹
explain顯示了MySQL如何使用索引來處理select語句以及連接表。他可以幫助選擇更好的索引和寫出更優化的查詢語句
explain顯示了很多列,各個關鍵字的含義如下:
- table:顧名思義,顯示這一行的數據是關于哪張表的;
- type:這是重要的列,顯示連接使用了何種類型。從最好到最差的連接類型為:const、eq_reg、ref、range、indexhe和ALL;
- possible_keys:顯示可能應用在這張表中的索引。如果為空,沒有可能的索引。可以為相關的域從where語句中選擇一個合適的語句;
- key: 實際使用的索引。如果為NULL,則沒有使用索引。很少的情況下,MySQL會選擇優化不足的索引。這種情況下,可以在Select語句中使用USE INDEX(indexname)來強制使用一個索引或者用IGNORE INDEX(indexname)來強制MySQL忽略索引;
- key_len:使用的索引的長度。在不損失精確性的情況下,長度越短越好;
- ref:顯示索引的哪一列被使用了,如果可能的話,是一個常數;
- rows:MySQL認為必須檢查的用來返回請求數據的行數;
- Extra:關于MySQL如何解析查詢的額外信息。
- 具體的各個列所能表示的值以及含義可以參考MySQL官方文檔介紹,地址:https://dev.mysql.com/doc/refman/5.7/en/explain-output.html
造成索引失效的場景
- where 子句中使用 != 或 <> 操作符,引擎將放棄使用索引而進行全表掃描。
- where 子句中使用 or 來連接條件,將導致引擎放棄使用索引而進行全表掃描,即使其中有條件帶索引也不會使用,這也是為什么盡量少用 or 的原因。
- 對于多列索引,不是使用的一部分,則不會使用索引。
- 如果列類型是字符串,那一定要在條件中將數據使用引號引用起來,否則不會使用索引。
- like的模糊查詢以 % 開頭,索引失效。
- 在 where 子句中對字段進行表達式操作,導致引擎放棄使用索引而進行全表掃描。
- 在 where 子句中對字段進行函數操作,導致引擎放棄使用索引而進行全表掃描。
- 在 where 子句中的 “=” 左邊進行函數、算術運算或其他表達式運算,導致系統將可能無法正確使用索引。
- 不適合鍵值較少的列(重復數據較多的列)。假如索引列TYPE有5個鍵值,如果有1萬條數據,那么 WHERE TYPE = 1將訪問表中的2000個數據塊。再加***問索引塊,一共要訪問大于200個的數據塊。如果全表掃描,假設10條數據一個數據塊,那么只需訪問1000個數據塊,既然全表掃描訪問的數據塊少一些,肯定就不會利用索引了。