MySQL學習筆記(第三天)
阿新 • • 發佈:2020-09-16
MySQL學習筆記(第三天)
參考文章:
1.1單表使用索引避免常見的索引失效
環境準備
create table `tb_seller` ( `sellerid` varchar (100), `name` varchar (100), `nickname` varchar (50), `password` varchar (60), `status` varchar (1), `address` varchar (100), `createtime` datetime, primary key(`sellerid`) )engine=innodb default charset=utf8mb4; insert into `tb_seller` (`sellerid`, `name`, `nickname`, `password`, `status`, `address`, `createtime`) values('alibaba','阿里巴巴','阿里小店','e10adc3949ba59abbe56e057f20f883e','1','北京市','2088-01-01 12:00:00'); insert into `tb_seller` (`sellerid`, `name`, `nickname`, `password`, `status`, `address`, `createtime`) values('baidu','百度科技有限公司','百度小店','e10adc3949ba59abbe56e057f20f883e','1','北京市','2088-01-01 12:00:00'); insert into `tb_seller` (`sellerid`, `name`, `nickname`, `password`, `status`, `address`, `createtime`) values('huawei','華為科技有限公司','華為小店','e10adc3949ba59abbe56e057f20f883e','0','北京市','2088-01-01 12:00:00'); insert into `tb_seller` (`sellerid`, `name`, `nickname`, `password`, `status`, `address`, `createtime`) values('itcast','傳智播客教育科技有限公司','傳智播客','e10adc3949ba59abbe56e057f20f883e','1','北京市','2088-01-01 12:00:00'); insert into `tb_seller` (`sellerid`, `name`, `nickname`, `password`, `status`, `address`, `createtime`) values('itheima','黑馬程式設計師','黑馬程式設計師','e10adc3949ba59abbe56e057f20f883e','0','北京市','2088-01-01 12:00:00'); insert into `tb_seller` (`sellerid`, `name`, `nickname`, `password`, `status`, `address`, `createtime`) values('luoji','羅技科技有限公司','羅技小店','e10adc3949ba59abbe56e057f20f883e','1','北京市','2088-01-01 12:00:00'); insert into `tb_seller` (`sellerid`, `name`, `nickname`, `password`, `status`, `address`, `createtime`) values('oppo','OPPO科技有限公司','OPPO官方旗艦店','e10adc3949ba59abbe56e057f20f883e','0','北京市','2088-01-01 12:00:00'); insert into `tb_seller` (`sellerid`, `name`, `nickname`, `password`, `status`, `address`, `createtime`) values('ourpalm','掌趣科技股份有限公司','掌趣小店','e10adc3949ba59abbe56e057f20f883e','1','北京市','2088-01-01 12:00:00'); insert into `tb_seller` (`sellerid`, `name`, `nickname`, `password`, `status`, `address`, `createtime`) values('qiandu','千度科技','千度小店','e10adc3949ba59abbe56e057f20f883e','2','北京市','2088-01-01 12:00:00'); insert into `tb_seller` (`sellerid`, `name`, `nickname`, `password`, `status`, `address`, `createtime`) values('sina','新浪科技有限公司','新浪官方旗艦店','e10adc3949ba59abbe56e057f20f883e','1','北京市','2088-01-01 12:00:00'); insert into `tb_seller` (`sellerid`, `name`, `nickname`, `password`, `status`, `address`, `createtime`) values('xiaomi','小米科技','小米官方旗艦店','e10adc3949ba59abbe56e057f20f883e','1','西安市','2088-01-01 12:00:00'); insert into `tb_seller` (`sellerid`, `name`, `nickname`, `password`, `status`, `address`, `createtime`) values('yijia','宜家家居','宜家家居旗艦店','e10adc3949ba59abbe56e057f20f883e','1','北京市','2088-01-01 12:00:00'); create index idx_seller_name_sta_addr on tb_seller(name,status,address);
a.全值匹配
對索引中所有列都指定具體值。該情況下,索引生效,執行效率高。
explain select * from tb_seller where name='小米科技' and status='1' and address='北京市'\G;
b.最左字首法則
如果索引了多列,要遵守最左字首法則。指的是查詢從索引的最左前列開始,並且不跳過索引中的列。
c.範圍查詢右邊的列,不能使用索引
根據前面的兩個欄位name , status 查詢是走索引的, 但是最後一個條件address 沒有用到索引。
d.不要在索引列上進行運算操作,否則索引將失效
![](https://img2020.cnblogs.com/blog/1525547/202009/1525547-20200916200828038-845841099.png)
e. 字串(varchar)不加單引號,造成索引失效
由於,在查詢時,沒有對字串加單引號,MySQL的查詢優化器,會自動的進行型別轉換,造成索引失效。
f.儘量使用覆蓋索引,避免select *
儘量使用覆蓋索引(只訪問索引的查詢(索引列完全包含查詢列)),減少select * 。
如果查詢列,超出索引列,也會降低效能。
TIP : using index :使用覆蓋索引的時候就會出現 using where:在查詢使用索引的情況下,需要回表去查詢所需的資料 using index condition:查詢使用了索引,但是需要回表查詢資料 using index ; using where:查詢使用了索引,但是需要的資料都在索引列中能找到,所以不需要回表查詢資料
g. 用or分割開的條件, 如果or前的條件中的列有索引,而後面的列中沒有索引,那麼涉及的索引都不會被用到。
示例,name欄位是索引列 , 而createtime不是索引列,中間是or進行連線是不走索引的 :
h. 以%開頭的Like模糊查詢,索引失效。
如果僅僅是尾部模糊匹配,索引不會失效。如果是頭部模糊匹配,索引失效。
解決方案 :
通過覆蓋索引來解決
i. is NULL , is NOT NULL 有時索引失效。
j. in 走索引, not in 索引失效。
【優化總結口訣】
全值匹配我最愛,最左字首要遵守;
帶頭大哥不能死,中間兄弟不能斷;
索引列上無計算,範圍之後全失效;
Like百分寫最右,覆蓋索引不寫星;
不等空值還有or,索引失效要少用;
VAR引號不可丟,SQL高階也不難!
未完待續......