linux系統mysql索引


索引

一、索引的分類

1.根據算法分類

1)主鍵索引

#1.建表時創建
create table test(id int primary key);
create table test(id int,primary key(id));

#2.添加主鍵索引
alter table test add primary key pri_key(id);

2)唯一建索引

#1.建表時創建
create table test(id int unique key);

#2.添加唯一建索引
alter table test add unique key uni_key(id);

3)普通索引

#1.添加普通索引
alter table test add index ljp_key(id);

4)全文索引

5)查看索引

#1.方式一:
mysql> show index from test10;

#2.方式二:
mysql> desc test10;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id    | int(11) | YES  | UNI | NULL    |       |
+-------+---------+------+-----+---------+-------+
1 row in set (0.00 sec)

PRI:主鍵索引
UNI:唯一建索引
MUL:普通索引

6)刪除索引

mysql> alter table test drop index index_key;

2.根據配置方法分類

1)注意事項

1.創建索引時會將數據重新進行排序
2.創建索引會占用磁盤空間,所以索引不是越多越好
3.在同一列上避免創建多種索引
4.避免在數據很長的字段上創建索引,如果要創建就創建前綴索引

2)前綴索引

#根據前四個字符創建前綴索引
mysql> alter table test add index index_key(name(4));

3)聯合索引

mysql> create database xiangqing;

mysql> create table xiangqin(id int,name varchar(20),gender enum('m','f'),age tinyint,money int,height int,weight int,looks tinyint);

mysql> insert xiangqin values(1,'qiudao','m',38,-200000,120,130,'10'),(2,'dilireba','f',18,400000,180,100,'60'),(3,'cxk','m',28,100000,170,120,'440'),(4,'fbb','f',18,1000000,165,85,'90');

#創建聯合索引
mysql> alter table xiangqin add index lh_key(money,gender,age,looks);

#聯合索引使用三種情況
1.部分走索引		money,gender,age
2.全部走索引		money,gender,age,looks
3.不走索引		 gender,age

二、explain的使用

1.explain語法

explain + DQL語句

mysql> explain select * from city where countrycode ='CHN' or countrycode ='USA';

#查詢中國和美國的數據
mysql> select * from city where countrycode ='CHN' or countrycode ='USA';
mysql> select * from city where countrycode in ('CHN','USA');
mysql> select * from city where countrycode = 'CHN' union all select * from city where countrycode = 'USA';

Extra(擴展)
	Using temporary 使用group by大概率出現
	Using filesort 使用了order by大概率出現
	Using join buffer 使用join on大概率出現

2.擴展group by

#一般與聚合索引一起使用

#建表
mysql> create table jixiao(id int,name varchar(20) charset utf8,jixiao int,product varchar(10) charset utf8);                                    
Query OK, 0 rows affected (0.03 sec)
#插入數據
mysql> insert jixiao values(1,'qiudao','1000000','房地產'),(2,'niulei','10000','房地產'),(3,'lijianpeng','100000','汽車'),(4,'qiandao','200000',' 汽車');
#查詢不同行業績效最高的人
mysql> select name,sum(jixiao),product from jixiao group by product;
+------------+-------------+-----------+
| name       | sum(jixiao) | product   |
+------------+-------------+-----------+
| qiudao     |     1010000 | 房地產    |
| lijianpeng |      300000 | 汽車      |
+------------+-------------+-----------+
2 rows in set (0.00 sec)
#查詢房地產行業績效最高的人
mysql> select name,sum(jixiao),product from jixiao group by product having product='房地產';
+--------+-------------+-----------+
| name   | sum(jixiao) | product   |
+--------+-------------+-----------+
| qiudao |     1010000 | 房地產    |
+--------+-------------+-----------+
1 row in set (0.00 sec)

3.查詢數據的方式

1)全表掃描

#1.什么是全表掃描
查詢數據時type類型為ALL

#2.什么情況全表掃描
1)查詢數據庫所有數據
	mysql> explain select * from country
2)沒有走索引
	沒設置索引
	索引損壞

2)索引掃描

1.index			#全索引掃描
	mysql> explain select Name from city;

2.range			#范圍查詢
	mysql> explain select * from city where countrycode ='CHN' or countrycode ='USA';
	#有限制查詢到的數據在總數據的20%以內,超過則走全文掃描,所以在查詢是可以使用limit限制
	mysql> explain select * from city where countrycode != 'CHN' limit 500;

3.ref			#精確查詢
	mysql> explain select * from city where countrycode ='CHN';

4.eq_ref		#使用join on時偶爾會出現

5.const			#查詢條件是唯一索引或主鍵索引
	mysql> explain select * from city where id=1;

6.system		#查詢級別與const一樣,當數據很少時為該級別

7.null			#不需要讀取數據,只需要獲取最大值或者最小值
	mysql> explain select max(population) from city;

三、索引的建立

1.索引的建立原則

1.能創建唯一索引就創建唯一索引

2.為經常需要排序、分組和聯合操作的字段建立索引

3.為常作為查詢條件的字段建立索引
	如果某個字段經常用來做查詢條件,那么該字段的查詢速度會影響整個表的查詢速度。
	因此,為這樣的字段建立索引,可以提高整個表的查詢速度。
	
4.盡量使用前綴來索引
	如果索引字段的值很長,最好使用值的前綴來索引。
		例如,TEXT和BLOG類型的字段,進行全文檢索,會很浪費時間。如果只檢索字段的前面的若干個字符,這樣可以提高檢索速度。
		
5.限制索引的數目
	索引的數目不是越多越好。每個索引都需要占用磁盤空間,索引越多,需要的磁盤空間就越大。
	修改表時,對索引的重構和更新很麻煩。越多的索引,會使更新表變得很浪費時間。

6.刪除不再使用或者很少使用的索引
	表中的數據被大量更新,或者數據的使用方式被改變后,原有的一些索引可能不再需要。數據庫管理員應當定期找出這些索引,將它們刪除,從而減少索引對更新操作的影響。

2.總結什么時候不走索引

1)沒有查詢條件,或者查詢條件沒有索引

#沒有查詢條件
mysql> explain select * from city;
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
|  1 | SIMPLE      | city  | ALL  | NULL          | NULL | NULL    | NULL | 4188 | NULL  |
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
1 row in set (0.00 sec)

#查詢條件沒有索引
mysql> explain select District from city;
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
|  1 | SIMPLE      | city  | ALL  | NULL          | NULL | NULL    | NULL | 4188 | NULL  |
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
1 row in set (0.00 sec)

2)查詢的結果占總數據的20%左右

#占總數據的18%,沒走索引
mysql> explain select * from city where population > 400000;

#占總數據的15%,走了索引
mysql> explain select * from city where population > 450000;

#如果數據量查詢就是表中大部分數據,可以用limit做限制
mysql> explain select * from city where population > 400000 limit 100;

3)索引損壞

4)查詢條件帶了特使符號(+,-)

#在=號左側有特殊符號,不走索引
mysql> explain select * from city where id-1=1;

#在=號右側有特殊符號,走索引
mysql> explain select * from city where id=3-1;

5)隱式轉換

#建表
mysql> create table test (id int ,name varchar(20),telnum varchar(10));
Query OK, 0 rows affected (0.04 sec)
#插入數據
mysql> insert into test values(1,'zs','110'),(2,'l4',120),(3,'w5',119),(4,'z4',112);
Query OK, 4 rows affected (0.00 sec)
Records: 4  Duplicates: 0  Warnings: 0
#建立索引
mysql> desc phonenum;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int(11)     | YES  |     | NULL    |       |
| name  | varchar(10) | YES  |     | NULL    |       |
| phone | varchar(10) | YES  | UNI | NULL    |       |
+-------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
#查詢語句級別全文掃描
mysql> explain select * from phonenum where phone=6666666;
+----+-------------+----------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table    | type | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+----------+------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | phonenum | ALL  | uni_key       | NULL | NULL    | NULL |    3 | Using where |
+----+-------------+----------+------+---------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)
#當給字符加上引號,查詢為索引掃描
mysql> explain select * from phonenum where phone='6666666';
+----+-------------+----------+-------+---------------+---------+---------+-------+------+-------+
| id | select_type | table    | type  | possible_keys | key     | key_len | ref   | rows | Extra |
+----+-------------+----------+-------+---------------+---------+---------+-------+------+-------+
|  1 | SIMPLE      | phonenum | const | uni_key       | uni_key | 13      | const |    1 | NULL  |
+----+-------------+----------+-------+---------------+---------+---------+-------+------+-------+
1 row in set (0.00 sec)

6)like "%_" 百分號在最前面不走

#走range索引掃描
EXPLAIN SELECT * FROM teltab WHERE telnum LIKE '31%';
#不走索引
EXPLAIN SELECT * FROM teltab WHERE telnum LIKE '%110';

7)聯合索引查詢不按照順序有可能不走索引

%linux%類的搜索需求,可以使用Elasticsearch -------> ELK
單獨引用聯合索引里非第一位置的索引列

CREATE TABLE t1 (id INT,NAME VARCHAR(20),age INT ,sex ENUM('m','f'),money INT);
ALTER TABLE t1 ADD INDEX t1_idx(money,age,sex);
DESC t1
SHOW INDEX FROM t1
#走索引的情況測試
EXPLAIN SELECT NAME,age,sex,money FROM t1 WHERE money=30 AND age=30  AND sex='m';
#部分走索引
EXPLAIN SELECT NAME,age,sex,money FROM t1 WHERE money=30 AND age=30;
EXPLAIN SELECT NAME,age,sex,money FROM t1 WHERE money=30  AND sex='m'; 
#不走索引
EXPLAIN SELECT  NAME,age,sex,money FROM t1 WHERE age=20
EXPLAIN SELECT NAME,age,sex,money FROM t1 WHERE age=30 AND sex='m';
EXPLAIN SELECT NAME,age,sex,money FROM t1 WHERE sex='m';


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM