一、索引的简单操作(增删改查)
创建索引
CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX index_name
[USING index_type]
ON table_name (index_col_name,...)
[UNIQUE|FULLTEXT|SPATIAL]:表示创建索引的类型,分别表示唯一索引、全文索引、空间索引;
[USING index_type]:表示索引的类型,索引类型有BTREE索引和HASH索引。
存储引擎为MyISAM和INNODB的表中只能使用BTREE;
存储引擎为MEMORY和heap的表中可以使用BTREE索引和HASH索引
注意:另一种创建索引语法
ALTER TABLE table_name ADD [UNIQUE|FULLTEXT|SPATIAL] INDEX [index_name] [index_type] (index_col_name,...)
查看索引
SHOW INDEX FROM table_name
删除索引
--删除指定表中指定名称的索引
ALTER TABLE table_name DROP INDEX index_name;
修改索引
在mysql中没有提供修改索引的指令,一般情况下,直接删除原索引,重新建立同名索引即可。
举例:增删改查索引:在那张表上执行add/drop那个索引
//添加索引
CREATE UNIQUE index index_prizecide on bsy_prizeinfo(prizecode);
//查看索引
show index from bsy_prizeinfo;
//删除索引
alter table bsy_prizeinfo drop index index_prizecode
//添加索引
alter table bsy_prizeinfo add UNIQUE index index_prizecode (prizecode);
二、索引类型
1)BTREE索引
2)HASH索引
3)空间索引
4)全文索引
三、索引策略
正确创建和使用索引是实现高性能查询的基础。
1)独立的列:索引列不能使表达式的一部分,也不能是函数的参数。
举例:
explain select * from emp where empno+1=100003;
explain select SQL_NO_CACHE * from emp where TIMESTAMPDIFF(day,hiredate,now())<=2
2)前缀索引和索引选择性
有时需要索引很长的字符列,索引变得大且慢,利用前缀索引,只索引列开始的部分字符,可以节约索引空间,提高索引效率。但也会降低索引的选择性。
索引的选择性是指:不重复的索引值(基数)和数据表的记录总数的比值。索引的选择性高,mysql在查找时过滤更多的行,则查询效率高。
举例:
select SQL_NO_CACHE count(DISTINCT loc)/count(*) from dept;
alter table dept add index index_loc (loc(7));
前缀索引是一种能使索引更小、更快的有效办法,但是有缺点:mysql无法使用前缀索引做order by 、group by、覆盖扫描。
3)多列索引
多列索引常见的错误是:为每一个列创建独立的索引,或者按照错误的顺序创建多列索引。
索引合并策略(index_merge):一定程度上可以使用表上的多个单列索引来定位指定的行。索引合并策略有时是一种优化的结果,但实际上更多时候说明了表上的索引建的很糟糕。检查查询和表的结构是不是最优,通过参数optimizer_switch来关闭索引合并功能。也可以使用ignore index提示优化器忽略掉某些索引。
举例:
explain select * from emp where deptno='24' or empno='4099904';
·当服务器对多个索引做相交操作时(and),你需要一个包含所有相关列的多列索引,而不是多个独立的单例索引。
·当服务器对多个索引做联合操作时(or),通常需要耗费大量CPU和内存资源在算法的缓存、排序、合并上。特别是当索引的选择性不高,需要合并扫描返回的大量数据的时候。
合适的索引顺序:多列索引中索引列的顺序意味着索引首先按照最左列进行排序,其次是第二列,等等。索引可以升序或降序进行扫描,以满足精确符合列顺序的order by、group by的distinct等子句。当不需要考虑排序和分组时,将选择性高的列放在前面通常是很好的。这是索引的作用只是用于优化where条件的查询。
4)聚簇索引
聚簇索引并不是一种单独的索引类型,而是一种数据存储方式。具体的细节依赖于其实现方式。因为无法把数据行存放在两个不同的地方,所以一个表只能有一个聚簇索引。
本章主要关注innodb。在innodb中聚簇索引中保存了索引列和数据行,聚族索引列是主键列,如果没有主键,innodb会选择一个唯一的非空索引代替。如果没有这样的索引,innodb会隐式定义一个主键来作为聚簇索引。
优点:
·数据访问更快。聚簇索引将索引和数据保存在同一个B-Tree中,因此聚簇索引中获取数据通常比在非聚簇索引中查找更快。
·使用覆盖索引扫描的查询可以直接使用页节点中的主键值。
缺点:
·二级索引(非聚簇索引)可能比想象的要更大,因为在二级索引的叶子节点包含了引用行的主键列。
·二级索引访问需要两次索引查找,而不是一次。通过二级索引查找行时,存储引擎需要找到二级索引的叶子节点获得对应的主键值,然后根据这个主键值去聚簇索引中查找到对应的行。即为:两次B-Tree查找。
InnoDB和MyISAM的数据分布对比