mysql數據庫字符集和索引


#什么是字符集
#字符集:是一個計算機支持的所有抽象字符的集合。
#字符是各種文字和符號的總稱,包括各國家文字、標點符號、圖形符號、數字等。
編碼:把人類可以識別的信息轉化為機算計認識的0和1
解碼:把機算計存儲的0和1轉化為人類可以識別的信息
亂碼:編碼解碼的過程,導致一些數據不能解析

ASCII:		美國

gbk		    中國,一個漢字占用2個字節,#范圍大於utf8
gbk2312		#范圍大於gbk
utf8		一個漢字占用3個字節
utf8mb4		一個漢字占用4個字節(utf8mb4不能轉化為utf8,因為utf8不支持表情符號)

shift-jis	日本
Euc-kr		韓國
Unicode		萬國碼(翻譯官)

json 翻譯官-- java python php

字符集修改要求:包含關系才可以修改(#小的可以轉化成大的,並且是兼容關系)
	ASCII碼可以轉化成任意編碼
	萬國碼可以轉化成任意語言
	
#查看centos字符集,字符集與SQL語句是否支持大小寫有關
mysql> show charset;
+----------+-----------------------------+---------------------+--------+
| Charset  | Description                 | Default collation   | Maxlen |
+----------+-----------------------------+---------------------+--------+

#查看校驗規則
mysql> show collation;
+--------------------------+----------+-----+---------+----------+---------+
| Collation                | Charset  | Id  | Default | Compiled | Sortlen |

#校驗規則
1.ci		不區分大小寫,SQL語句與SQL數據(字符集修改為ci的話,查找已存在的數據庫名還是區分大小寫,創建新庫表不區分大小寫,導致相同字段等不能添加)(utf8_general_ci)
2.cs		區分大小寫
3.bin		區分大小寫(utf8_bin)	

#設置字符集
1.終端(小地球)
2.命令行
-------------------C7中設置字符集(#反饋中文)
臨時
LANG=zh_CN.UTF-8	
永久
vim /etc/locale.conf
LANG=zh_CN.UTF-8
-------------------CS6設置字符集
vim /etc/sysconfig/i18n
LANG=zh_CN.UTF-8
3.數據庫字符集的修改(默認是拉丁)
	1)預編譯cmake階段
	cmake . 
	-DDEFAULT_CHARSET=utf8 \
	-DDEFAULT_COLLATION=utf8_general_ci \
	-DWITH_EXTRA_CHARSETS=all \
	2)配置文件vim /etc/my.cnf
	character_set_server=utf8
	3)SQL語句	
		#庫
		create database xx charset utf8;
		show create database xx;(查看數據庫字符集)
		
		庫下建表,#庫的字符集就是表的字符集
		create table tb1(id int);
		show create table tb1;((查看數據庫中表的字符集))
		
		修改庫的字符集(#注意字符集的范圍大小)
		alter database xx charset utf8;
		mysql> show create database xx;	#實時查看建庫字符集
		
		批量修改庫的字符集
		1.可以用循環 
		alter database % utf8;(不能直接使用SQL語句批量修改數據庫字符集)
		mysql -uroot -p1 -e 'alter database $xx charset utf8'
		2.數據導出(-A導出所有庫,-B導出指定庫)
		mysqldump -uroot -p123 -B tb3 > a.sql
		:%s#DEFAULT CHARACTER SET latin1#DEFAULT CHARACTER SET utf8#g
		### drop database tb3;
		mysql -uroot -p123 < a.sql
		
		#表
		指定字符集建表
		create table xx(id int) charset utf8mb4;
		show create table xx;
		修改表的字符集(#屬性)
		alter table xx charset utf8;
		show create table xx;
		
#修改字符集
mysql> alter table tb1 charset gbk;
mysql> alter table tb1 charset utf8;
mysql> alter table tb1 charset utf8_bin;
ERROR 1115 (42000): Unknown character set: 'utf8_bin'

mysql> show charset;
+----------+
| Charset  |
+----------+
| big5  
| dec8  
| cp850 
| hp8   
| koi8r 
| latin1
| latin2
| swe7  
| ascii 
| ujis  
| sjis  
| hebrew

#不能添加括號內容
mysql> show create table tb4(id int);
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(id int)' at line 1

mysql> show create table tb4;
| Table | Create Table                                                       
| tb4   | CREATE TABLE `tb4` (
  `id` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=gbk |

#create database if not exists xx;

索引

#索引
1.索引就好比一本書的目錄,它能讓你更快的找到自己想要的內容。
2.索引讓獲取的數據更有目的性,從而'提高數據庫檢索數據的性能'。

#索引的種類
1.BTREE:
	B+tree   葉節點有快速通道,速度更快一點
	B*tree   枝節點葉節點都有快速通道,速度更快
2.HASH		HASH索引(memery存儲引擎才支持)
3.FULLTEXT:	全文索引(myisam存儲引擎才支持)速度較慢
4.RTREE		R樹索引

#根據磁盤吞吐量(IO)判斷索引檢索速度
select * from table where id=38;
#BTREE
	根節點
	枝節點
	葉節點	#存儲真實數據

索引根據算法分類

索引:
	是建立在數據庫'表的字段上面的',當where條件后面'接的字段'有索引的時候,'會提高數據獲取的速度'
	
1.主鍵索引(聚集索引)(Btree)
#創建表的時候創建主鍵索引(主鍵屬性就是主鍵索引,因為有primary key)
creat table test(id int primary key auto_increment comment '學號')
create table test1(id int auto_increment,primary key(id));
#查看索引(Key_name==PRIMARY,主鍵只顯示PRIMARY)(有索引才會顯示)
show index from test;
+-------+------------+----------+--------------+-------------+-----------+--
#  表         			索引名		 聯合索引的順序	字段名
| 'Table' | Non_unique | 'Key_name' | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | 'Index_type' | Comment | Index_comment |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| 'tb4'   |          0 | 'PRIMARY'  |            1 | idd         | 'A'         |           0 |     NULL | NULL   |      | 'BTREE'      |         |               |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
#還可以用desc查看索引類型
mysql> desc test;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | 'Key' | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id    | int(11) | NO   | 'PRI' | 0       |       |
+-------+---------+------+-----+---------+-------+

#show
mysql> show create table test;
| Table | Create Table                                                       
| test  | CREATE TABLE `test` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  UNIQUE KEY `id` (`id`)  #
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |

#在已存在的表添加主鍵索引(名字)
1).給指定列增加屬性
alter table test1 add primary key pri_id(id);
show index from test1;
desc test1;
2).修改列屬性
alter table xx modify id int primary key auto_increment;

#刪除主鍵索引
mysql> alter table test3 drop primary key;
mysql> alter table cs drop index primary key;
ERROR 1064 (42000):

#偽主鍵
mysql> desc test3;
mysql> alter table test3 add primary key(id);
mysql> desc test3;
mysql> alter table test3 drop primary key;
mysql> desc test3;
mysql> alter table test3 add unique key 1_key(id)
mysql> desc test3;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id    | int(11) | NO   | PRI | 0       |       |
+-------+---------+------+-----+---------+-------+
mysql> alter table test3 add name varchar(4);
mysql> desc test3;
mysql> alter table test3 add unique key 2_key(name);
mysql> desc test3;
+-------+------------+------+-----+---------+-------+
| Field | Type       | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| id    | int(11)    | NO   | PRI | 0       |       |  #
| name  | varchar(4) | YES  | UNI | NULL    |       |
+-------+------------+------+-----+---------+-------+
mysql> alter table test3 drop primary key;
ERROR 1091 (42000): Can't DROP 'PRIMARY'; check that column/key exists
mysql> desc test3;
+-------+------------+------+-----+---------+-------+
| Field | Type       | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| id    | int(11)    | NO   | PRI | 0       |       |
| name  | varchar(4) | YES  | UNI | NULL    |       |
+-------+------------+------+-----+---------+-------+
mysql> alter table test3 add primary key(id);
mysql> desc test3;
mysql> alter table test3 drop primary key;
mysql> desc test3;
+-------+------------+------+-----+---------+-------+
| Field | Type       | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| id    | int(11)    | NO   | PRI | 0       |       |  #
| name  | varchar(4) | YES  | UNI | NULL    |       |
+-------+------------+------+-----+---------+-------+
mysql> alter table test3 add unique key(id);  #該列添加了唯一鍵,顯示pri
mysql> desc test3;
+-------+------------+------+-----+---------+-------+
| Field | Type       | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| id    | int(11)    | NO   | PRI | 0       |       |
| name  | varchar(4) | YES  | UNI | NULL    |       |
+-------+------------+------+-----+---------+-------+
mysql> alter table test3 add primary key(a4);  #另一列添加主鍵(主鍵飄移)
mysql> desc test3;
+-------+------------+------+-----+---------+-------+
| Field | Type       | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| id    | int(11)    | NO   | UNI | 0       |       |
| name  | varchar(4) | YES  | UNI | NULL    |       |
| age   | varchar(6) | YES  | UNI | NULL    |       |
| a4    | int(11)    | NO   | PRI | 0       |       |
+-------+------------+------+-----+---------+-------+

2.唯一鍵索引(#該列不能有重復數據)(Btree)(游戲名)----------------------
#創建表的時候創建唯一鍵索引
create table test2(id int unique key not null auto_increment comment '學號');
#在已存在的表添加唯一鍵索引(name字段要存在,uni_key不能重復)
alter table test2 add name int;
alter table test3 add unique key(a4);	#不給唯一鍵名字,默認為字段名
alter table test2 add unique key uni_key(name);	 #給唯一鍵名字

#modify,使用modify可以修改主鍵,但是不能修改唯一鍵
alter table xx modify id int primary key auto_increment;
alter table xx modify a5(unique key);
ERROR 1064 (42000):

mysql> show index from test2; (#可以看到key的名字)
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | 'Key_name' | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | 'Index_type' | Comment | Index_comment |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| test  |          0 | 'id'       |            1 | 'id'          | A         |           0 |     NULL | NULL   |      | 'BTREE'      |         |               |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+

mysql> show index from test3\G
*************************** 1. row ***************************
        Table: test3
   Non_unique: 0
     Key_name: 1_key	#唯一鍵的名字,刪除的時候使用
 Seq_in_index: 1
  Column_name: id		#字段名
    Collation: A
  Cardinality: 0
     Sub_part: NULL
       Packed: NULL
         Null: 
   Index_type: BTREE
      Comment: 
Index_comment:

mysql> desc test2;  #不能看到key的名字
+-------+---------+------+-----+---------+----------------+
| Field | Type    | Null | Key | Default | Extra          |
+-------+---------+------+-----+---------+----------------+
| id    | int(11) | NO   | PRI | NULL    | auto_increment |
| name  | int(11) | YES  | UNI | NULL    |                |
+-------+---------+------+-----+---------+----------------+

mysql> show create table test;
| Table | Create Table                                                       
| test  | CREATE TABLE `test` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  UNIQUE KEY `id` (`id`)  #唯一鍵名,字段名
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |	#字符集


#判斷一列能否做唯一建索引
1)查看指定列數據總數(數據數)
select count(name) from city;
去重查看指定列數據總數
select distinct(name) from city;
mysql> select count(distinct(name)) from city;
2)創建唯一鍵索引
alter table test2 add unique key pri_id(name);
desc test2;

#注意:創建唯一建索引或主鍵索引的列不能有重復數據


3.普通索引(輔助索引),輔助查詢(可以在已存在的索引字段中添加普通索引,但是索引名肯定是不能重復的)-------------------------------------------------
#已存在的表才能創建普通索引
alter table city add index in_name(name);
create index innn_a4 on test3(a6);

mysql> show index from test3\G
*************************** 7. row ***************************
        Table: test3
   Non_unique: 1
     Key_name: in_na		#索引名
 Seq_in_index: 1
  Column_name: a5
    Collation: A
  Cardinality: 0
     Sub_part: NULL
       Packed: NULL
         Null: YES
   Index_type: BTREE
      Comment: 
Index_comment: 

mysql> desc test3;
+-------+------------+------+-----+---------+-------+
| Field | Type       | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| id    | int(11)    | NO   | PRI | 0       |       |
| name  | varchar(4) | YES  | UNI | NULL    |       |
| age   | varchar(6) | YES  | UNI | NULL    |       |
| a4    | int(11)    | NO   | UNI | 0       |       |
| a5    | int(11)    | YES  | MUL | NULL    |       |	#mul普通索引
+-------+------------+------+-----+---------+-------+

4.全文索引(一般用在文章里,針對一句話)----------------
mysql> create table txt(id int,bookname varchar(12),wenzhang text,fulltext(wenzhang));
mysql> select * from txt where match(wenzhang) against('查詢完整的內容'); 

#主鍵索引 > 唯一鍵索引 > 普通索引優先級(優先級高的有效 顯示)
#主鍵索引只能創建一個,唯一鍵索引能創建多個
#唯一鍵索引速度最快,能創建唯一鍵索引就創建 唯一鍵索引
#不經常用的字段,不要創建索引
#刪除索引的時候按照索引的名字刪除
#索引的名字不用指定,索引名=字段名 == 索引名_n

#添加主鍵索引,唯一鍵索引,普通索引
$$: primary key  	unique key		index
alter table xx add $$ suo_name(name);

查看索引

#方式一:
show index from city;

#方式二:
mysql> desc city;
+-----+
| Key |
+-----+
| PRI |		#主鍵索引
| MUL |		#普通索引
| UNI |		#唯一鍵索引
| MUL |
+-----+

mysql> desc test3;
+-------+------------+------+-----+---------+-------+
| Field | Type       | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| id    | int(11)    | NO   | PRI | 0       |       |
| name  | varchar(4) | YES  |     | NULL    |       |
| age   | varchar(6) | YES  | UNI | NULL    |       |
| a4    | int(11)    | NO   | UNI | 0       |       |
| a5    | int(11)    | YES  | MUL | NULL    |       |
| a6    | int(11)    | YES  |     | NULL    |       |
+-------+------------+------+-----+---------+-------+

#方式三
show create table xx;
mysql> show index from test3;
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| test3 |          0 | 1_key    |            1 | id          | A         |           0 |     NULL | NULL   |      | BTREE      |         |               |
| test3 |          0 | id       |            1 | id          | A         |           0 |     NULL | NULL   |      | BTREE      |         |               

#使用多種方式查看表內主鍵,可以查看索引的種類(desc),索引名(Key_name)
#和索引字段(Column_name),前綴索引的順序,索引的類型
#通過分析字段名和索引名可以查看一個字段是否有多個索引(與索引優化有關)

刪除索引

#刪除主鍵索引
mysql> alter table test3 drop primary key;
#刪除唯一鍵索引,普通索引
mysql> alter table city drop index index_name;


索引根據配置文件分類

1.前綴索引
2.聯合索引

注意

1.創建索引的時候會對數據進行重新排序('耗時',排序規則多樣)
2.創建索引的時候會'占用磁盤空間',所以索引不是越多越好
3.在'同一列'上避免創建多種索引
4.避免在數據'很長的字段上創建索引',如果要創建就創建前綴索引,增加創建索引的時候的排序速度

前綴索引(列)

#添加前綴索引為4(前綴索引並不是越小越好)
太小的索引值會是數據查找的精確度降低
無論字段有沒有其他索引,都可以添加前綴索引

#添加主鍵和前綴索引
mysql> alter table test3 add primary key p_id(name(4));
#添加唯一鍵和前綴索引
mysql> alter table test3 add unique key prrri_id(name(4));
#添加普通索引和前綴索引
mysql> alter table test3 add index suo_name(name(4));

聯合索引(復合索引)(字段)

#命名規則:表名_字段名
1、需要加索引的字段,在'where條件中使用'
2、'數據量少'的字段不需要加索引
3、如果where條件中是'OR關系',加索引不起作用
4、符合最左原則('有特例',解決辦法是將索引字段的順序調換一下)

create table xq(id int primary key,name varchar(4),gender enum('m','f'),age int);
insert xq values(1,'xx','m','18');
insert xq values(2,'xx','m','18');
insert xq values(3,'xx','m','18');
insert xq values(4,'xx','m','18');
show index from xq;
+-------+------------+----------+--------------+
| Table | Non_unique | Key_name | Seq_in_index 
+-------+------------+----------+--------------+
| xq    |          0 | PRIMARY  |            1 
#創建聯合索引(聯合索引有聯合順序)(最常用的字段創建聯合索引)
alter table xq add index ls_key(id,name,gender);
show index from xq;
| xq    |          0 | PRIMARY  |            1  id
| xq    |          1 | ls_key   |            1  id
| xq    |          1 | ls_key   |            2  name
| xq    |          1 | ls_key   |            3  gender
#聯合索引3種情況
1.全部走索引(1開頭)
2.部分走索引(1開頭)
3.不走索引  (不以1開頭)

explain

#作用
explain顯示了MySQL如何使用'索引'來處理select語句以及'連接表'。可以幫助選擇更好的索引和寫出更優化的查詢語句。
#語法
explain + select語句

mysql> explain select * from test2;
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
|  1 | SIMPLE      | test2 | index | NULL          | uni_key | 5       | NULL |    1 | Using index |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+

mysql> explain select * from test2\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: test2		#表
         type: index		#最好到最差的連接類型為const、eq_reg、ref、range、indexhe和all
possible_keys: NULL			#表中的索引
          key: uni_key		#實際使用的索引,強制(use index index_name),忽略(ignore index index_name)
      key_len: 5			#使用的索引的長度(越小越好)
          ref: NULL			#顯示索引的哪一列被使用了,如果可能的話,是一個常數
         rows: 1			#必須檢查的用來返回請求數據的行數
        Extra: Using index   #查詢的次數,當查詢的數據量較大的時候,並不准確

extra:
	using temporary 使用了group by出現這個
	using filesort	使用了order by出現這個
	using join buffer 使用了join on出現這個
	
#查詢中國和美國的數據
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';
速度: union all 	> 	in	>	or
#使用explain查看
mysql> explain select * from city where countrycode='CHN' union all select * from city where countrycode='USA';
| 'id' | select_type  | table      | 'type' | possible_keys | key         | key_len | 'ref'   | 'rows' | Extra                 |
+----+--------------+------------+------+---------------+-------------+-----
|  1 | PRIMARY      | city       | 'ref'  | CountryCode   | CountryCode | 3       | const |  363 | Using index condition |
|  2 | UNION        | city       | ref  | CountryCode   | CountryCode | 3       | const |  274 | Using index condition |
| NULL | UNION RESULT | <union1,2> | ALL  | NULL          | NULL        | NULL    | NULL  | NULL | Using temporary

#id與執行順序有關
#select_type 索引類型
#type 是explain的類型
#key_len 是前綴索引的長度
#rows 查詢的次數,當查詢的數據量較大的時候,並不准確(合並重復項)

擴展group by


create database fang;
use fang;
#建表
mysql> create table jixiao(id int,name varchar(20) charset utf8,jixiao int,product varchar(10) charset utf8); 
show create table fz;
show tables;
desc fz;
#插入數據
mysql> insert jixiao values(1,'qiudao','1000','房地產'),(2,'niulei','10','房地產'),(3,'lijianpeng','100','汽車'),(4,'qiandao','200','汽車');
select count(*) from fz;
#查詢不同行業績效最高的人
mysql> select name,sum(jixiao),product from jixiao group by product;
+------------+-------------+-----------+
| name       | sum(jixiao) | product   |
+------------+-------------+-----------+
| qiudao     |     1010000 | 房地產    |
| lijianpeng |      300000 | 汽車      |
+------------+-------------+-----------+

#查詢房地產行業績效最高的人
mysql> select name,sum(jixiao),product from jixiao group by product having product='房地產';
+--------+-------------+-----------+
| name   | sum(jixiao) | product   |
+--------+-------------+-----------+
| qiudao |     1010000 | 房地產    |
+--------+-------------+-----------+

select name,sum(jixiao),product from jixioa group by product;
select name,sum(jixiao),product from jixioa group by product having 字段='值';

#1.對group by后面的字段去重
#1.sum() 根據group by的值 相加
#having條件語句
select 字段1,sum(字段2),字段3... from 表1 ... group by 字段x having 字段='值'; 

查詢數據的級別

ip

1.全表掃描(type類型是all),不走索引,查詢速度最慢
#查看結果來判斷查詢級別
mysql> explain select * from country;
+----+-------------+---------+------+---------------+------+---------+------
| id | select_type | table   | type |
+----+-------------+---------+------+---------------+------+---------+------
|  1 | SIMPLE      | country | ALL  |
#查看字段是否有索引
mysql> desc city;
+-------------+----------+------+-----+---------+----------------+
| Field       | Type     | Null | Key | Default | Extra          |
+-------------+----------+------+-----+---------+----------------+
| ID          | int(11)  | NO   | PRI | NULL    | auto_increment |
| Name        | char(35) | NO   |     |         |                |
| CountryCode | char(3)  | NO   | MUL |         |                |
| District    | char(20) | NO   |     |         |                |
| Population  | int(11)  | NO   |     | 0       |                |
+-------------+----------+------+-----+---------+----------------+
查看結果來判斷查詢級別
mysql> explain select District from city;
+----+-------------+-------+------+
| id | select_type | table | type |
+----+-------------+-------+------+
|  1 | SIMPLE      | city  | ALL  |

#全表掃描的情況
一:查詢數據庫所有數據的時候(select *)
二:有索引,但是沒有走索引
	沒有設置索引 (desc xx;)
	索引損壞
explain select name from country;
desc 
---------------------------------------------------------------
2.索引掃描'級別'
一:index			慢,全索引掃描(!=)
	explain select * from city;
	explain select * from city where countrycode !='CHN'
二:range			范圍查詢(or ><)(范圍要在總數的 20%以內左右),limit,older by
	explain select * from city where countrycode='CHN'or countrycode='USA';
	explain select * from city where countrycode='CHN'or countrycode='USA' or countrycode='BRA' limit 100;
三:ref			精確查詢(=)
	explain select * from city where countrycode='CHN'
四:eq_ref		使用join on

五:const			查詢條件是唯一索引或者主鍵索引,#列
	explain select * from city where id=1;
六:system		快,查詢級別與const一樣,當數據很少的時候為該級別,#列

七:null			使用索引查詢表的數量的時候,#列
	desc city;
	alter table city add index aa(population);
	explain select max(population) from city;
	explain select min(population) from city;

索引的建立

#索引的建立原則
1.能創建唯一索引就創建唯一索引
2.為經常需要排序,分組,聯合的字段建立索引
3.為經常查詢的字段建立索引
4.盡量使用前綴索引
5.限制索引的數目,刪除很少使用的索引

不走索引的情況

1.'沒有查詢條件',或者'查詢條件沒有索引'
2.查詢的結果占總數據的'20%左右以上'
3.'要查詢的數據'就是表中的大部分數據
4.索引損壞(反復建立 刪除)
5.查詢條件帶了特殊符號(+ —)
	#'='左側有特殊符號
	mysql> select * from city where id-1=1;
+----+----------+-------------+----------+------------+
| ID | Name     | CountryCode | District | Population |
+----+----------+-------------+----------+------------+
|  2 | Qandahar | AFG         | Qandahar |     237500 |
+----+----------+-------------+----------+------------+
mysql> explain select * from city where id-1=1;
| id | select_type | table | type |
|  1 | SIMPLE      | city  | ALL  |  #
	#'='右側有特殊符號
	mysql> select * from city where id=3-1;
+----+----------+-------------+----------+------------+
| ID | Name     | CountryCode | District | Population |
+----+----------+-------------+----------+------------+
|  2 | Qandahar | AFG         | Qandahar |     237500 |
+----+----------+-------------+----------+------------+
mysql> explain select * from city where id=3-1;
| id | select_type | table | type  | 
|  1 | SIMPLE      | city  | const |  #

6.隱式轉換(字段類型設置與插入類型不同,導致不走索引)
#建表
mysql> create table cs(id int,name varchar(10));
#插入數據
mysql> insert cs values(1,'zz'),(2,007);
#建立索引
mysql> alter table cs add unique key uu_key(id);
mysql> alter table cs add unique key uuu_key(name);
mysql> desc cs;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int(11)     | YES  | UNI | NULL    |       |
| name  | varchar(10) | YES  | UNI | NULL    |       |
+-------+-------------+------+-----+
mysql> explain select * from cs where name='007';
mysql> explain select * from cs where name=007;

7.%在最前面不走索引(like %x)
8.聯合索引查詢不按順序

#int類型不加引號


免責聲明!

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



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