2、普通索引的创建
直接创建索引
CREATE INDEX index_name ON tablename(column(length))
修改表结构
ALTER TABLE table_name ADD INDEX index_name ON (column(length))
创建表时指定索引
CREATE TABLE tablename
(
col_name1 type,
col_name2 type,
INDEX index_name(col_name)
);
3、唯一索引的创建
索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。
直接创建唯一索引
CREATE UNIQUE INDEX indexName ON tablename(column(length))
修改表结构
ALTER TABLE table_name ADD UNIQUE indexName ON (column(length))
创建表时直接指定
CREATE TABLE tablename
(
col_name1 type,
col_name2 type,
UNIQUE INDEX index_name(col_name)
);
4、主键索引的创建
修改表结构
ALTER TABLE table_name ADD PRIMARY KEY(col_name)
创建表时直接指定
CREATE TABLE tablename
(
col_name1 type,
col_name2 type,
PRIMARY KEY(col_name)
);
5、复合索引的创建
直接创建复合索引
CREATE INDEX indexName ON tablename(col_name1,col_name2)
修改表结构
ALTER TABLE table_name ADD INDEX indexName(col_name1,col_name2)
创建表时直接指定
CREATE TABLE tablename
(
col_name1 type,
col_name2 type,
INDEX index_name(col_name1,col_name2)
);
6、全文索引的创建
直接创建全文索引
CREATE FULLTEXT INDEX indexName ON tablename(col_name)
修改表结构
ALTER TABLE table_name ADD FULLTEXT INDEX indexName(col_name)
创建表时直接指定
CREATE TABLE tablename
(
col_name1 type,
col_name2 type,
FULLTEXT INDEX index_name(col_name)
);
在使用全文索引时,需要借助MATCH AGAINST操作,而不是一般的WHERE语句加LIKE。全文索引的限制比较多,比如只能使用MyISAM存储引擎,比如只能在CHAR、VARCHAR、TEXT上设置全文索引。比如搜索的关键字默认至少要4个字符,比如搜索的关键字太短就会被忽略掉。
SELECT * FROM tablename WHERE MATCH(col_name) AGAINST('pattern');
col_name为全文索引列,'pattern'为匹配的字符串
7、索引的删除
DROP INDEX [indexName] ON tablename;
ALTER TABLE tablename DROP INDEX indexname;
8、索引信息的查看
SHOW INDEX FROM table_name;
9、索引的注意事项
A、索引不会包含有null值的列
在数据库设计时不要让字段的默认值为null。
B、使用短索引
C、索引列排序
因此数据库默认排序可以符合要求的情况下不要使用排序操作;尽量不要包含多个列的排序,如果需要最好给这些列创建复合索引。
D、like语句操作
一般情况下不推荐使用like操作,如果非使用不可。like “%aaa%”不会使用索引而like “aaa%”可以使用索引。
E、不要在列上进行运算
在索引列上进行运算将导致索引失效而进行全表扫描,例如
SELECT * FROM table_name WHERE YEAR(column_name)<2017;
F、不使用not in和操作
四、索引查询速度比较
1、插入记录
create procedure addStudent(in num int)
begin
declare i int;
set i=1;
delete from TStudent;
while num>=i do
insert TStudent values
(
LPAD(convert(i,char(10)),10,'0'),
CreateName(),
if(ceil(rand()*10)%2=0,'男','女'),
RPAD(convert(ceil(rand()*1000000000000000000),char(18)),18,'0'),
Concat(convert(ceil(rand()*10)+1980,char(4)),'-',LPAD(convert(ceil(rand()*12),char(2)),2,'0'),'-',LPAD(convert(ceil(rand()*28),char(2)),2,'0')),
Concat(PINYIN(sname),'@hotmail.com'),
case ceil(rand()*3) when 1 then '网络与网站开发' when 2 then 'JAVA' ELSE 'NET' END,
NOW()
);
set i=i+1;
end while;
select * from TStudent;
end
修改addStudent存储过程,插入500000条记录
call addStudent(500000);
SQL语句查询×××号cardID以12345开头的学生。
select * from TStudent where cardID like '12345%'
花费时间为1.27秒
2、给×××列添加索引
alter table TStudent add index cardidIndex(cardID);
SQL语句查询×××号cardID以12345开头的学生。
select * from TStudent where cardID like '12345%'
花费时间31毫秒。
2、使用覆盖索引的SQL语句
Tstudent表cardID列创建了索引,SQL语句查找的列是cardID,查找条件也是cardID,就会使用cardID索引进行查找,不需要扫描表的页。
explain select sname from TStudent where sname like '刘%';
执行结果Extra 出现using index,说明是使用覆盖索引查找。
3、使用覆盖索引实现order by排序
在MySQL中的ORDER BY有两种排序实现方式:
A、利用有序索引获取有序数据
B、文件排序
使用EXPLAIN分析SQL查询时,利用有序索引获取有序数据显示Using index。而文件排序显示Using filesort。
explain select email from TStudent order by email;
email列没有索引,SQL语句的查询计划可以看到Extra是using filesort,说明是将结果在内存中排序,需要额外时间开销。
给Email列添加索引后,
alter table TStudent add index emailIndex(email);
explain select email from TStudent order by email;