1.什么是索引
? 在数据量和访问量不大的情况下,MySQL的访问时非常快速的,是否加索引对访问影响不大。但是当数据和访问量剧增的时候,就会发现MySQL变慢,甚至down掉,这就必须考虑优化SQL了。给数据库建立正确合理的索引,是MySQL优化的一个重要手段。
? 索引的目的在于提高查询效率,可以类比字典,如果要查"mysql"这个单词,我们肯定需要定位到m字母,然后从前往后找到字母y,再找到剩下的"sql"。如果没有索引,那么你可能需要把所有单词看一遍才能找到你想要的。出了词典,生活中随处可见索引的例子,如火车站的车次表、图书的目录等。它们的原理都是一样的,通过不断的缩小想要获取数据的范围来筛选出想要的结果,同时把随机的时间变成顺序的时间,也就是我们总是通过一种查找方法来锁定数据。
? 在创建索引时,需要考虑哪些列会用于SQL查询,然后为这些列创建一个或多个索引。事实上,索引也是一种表,保存着主键或索引字段,以及一个能将每个记录只想实际表的指针(非聚簇索引和聚簇索引,一个在索引中保存的是字段值的地址,一个保存的就是字段的值)。数据库用户是看不到索引的,它们只是用来加速查询的。数据库搜索引擎使用索引来快速定位记录。
? INSERT 和 UPDATE 语句在拥有索引的表中执行会花费更多的时间,而 select 语句却会执行得更快,这是因为在进行插入和更新时,数据库也需要插入或更新索引值。
2.索引的创建
2.1 索引类型
- UNIQUE (唯一索引):不可能出现相同的值,可以有NULL值;
- INDEX (普通索引):允许出现相同的索引内容;
- PRIMARY KEY (主键索引):不允许出现相同的值;
- FULLTEXT INDEX (全文索引):可以针对值中的某个单词,但 效率确实不敢恭维;
- 组合索引:实质上是将多个字段建到一个索引里,列值得组合必须唯一
2.2 添加索引的几种方法
使用ALTER 语句对表添加索
ALTER TABLE 应用于数据表创建完毕之后再添加
ALTER TABLE tab_identity ADD UNIQUE index_test (name);
使用create语句对表添加索引
CREATE INDEX 可用于对表增加 普通索引 和 UNIQUE 索引,可用于建表时创建索引。
create INDEX iden_index on tab_identity(name)
3.索引的删除
删除索引可以使用 ALTER TABLE 或 DROP INDEX 语句来实现。DROP INDEX 可以在 ALTER TABLE 内部作为一条语句处理,其格式如下:
drop index index_name on table_name;
alter table table_name drop index index_name;
alter table table_name drop primary key;
4.索引失效
4.1 索引不会含有NULL值
只要列中包含有NULL值,都将不会被包含在索引中,符合索引中只要有一列含有NULL值,那么这一列对于此复合索引就是无效的。
4.2 索引列排序
MySQL查询只使用一个索引,因此如果where子句中已经使用了索引的话,那么 order by 中的列是不会使用索引的。因此数据库默认排序可以符合要求的情况下不要使用排序操作,尽量不要包含多个列的排序,如果需要最好给这些列建复合索引。
4.3 like语句操作
一般情况下不鼓励使用like操作,如果非用不可,注意正确的使用方式。like '%aaa%'不会使用索引,而 like ‘aaa%’ 可以使用索引.
4.4 不使用 NOT IN、<>、!=操作,但是<、<=、=、>、>=、BETWEEN、IN是可以用到索引的
4.5 索引要建立在经常进行select操作的字段上
这是因为,如果这些列很好用到的话,那么有无索引并不能明显改变查询速度。相反,由于增加了索引,反而降低了系统的维护速度和增大了空间需求。
4.6 索引要建立在值比较唯一的字段上
4.7 对于那些定义为text、image、bit数据类型的别不应该增加索引。因为这些列的数据要么相当大,要么取值很少
4.8 在 where 和 join 中出现的列需要建立索引
4.9 where的查询条件里有不等号(where column !=…),MySQL将无法使用索引
4.10 如果where子句的查询条件里使用了函数(如:where DAY(column)=…),MySQL将无法使用索引
4.11 在join操作中(需要从多个数据表提取数据时),MySQL只有主键和外检的数据类型相同时才使用索引,否则即使建立了索引也不会使用
5.查看索引
show KEYS FROM tab_identity;
explain SELECT * FROM tab_identity where name LIKE '谢%'
|