书接上篇,本文将列出7种不适合创建索引的情况
1. 不适合创建索引的7种情况
1. 在where中使用不到的字段,不要设置索引
WHERE条件(包括GROUP BY、ORDER BY)里用不到的字段不需要创建索引,索引的价值是快速定位,如果起不到定位的字段通常是不需要创建索引的。举个例子:
SELECT course_id,student_id, create_time
FROM student_info
WHERE student_id = 41251;
因为我们是按照student_id来进行检索的,所以不需要对其他字段创建索引,即使这些字段出现在SELECT 字段中。
2. 数据量小的表最好不要使用索引
如果表记录太少,比如少于1000个,那么是不需要创建索引的。表记录太少,是否创建索引对查询效率的影响并不大
。甚至说,查询花费的时间可能比遍历索引的时间还要短,索引可能不会产生优化效果。
3. 有大量重复数据的列上不要建立索引
在条件表达式中经常用到的不同值较多的列上建立索引,但字段中如果有大量重复数据,也不用创建索引。比如在学生表的"性别
"字段上只有“男”与“·女"两个不同值,因此无须建立索引。如果建立索引,不但不会提高查询效率,反而会严重降低数据更新速度
。
举例 1 :要在 100 万行数据中查找其中的 50 万行(比如性别为男的数据),一旦创建了索引,你需要先访问 50 万次索引,然后再访问 50 万次数据表,这样加起来的开销比不使用索引可能还要大。
举例 2 :假设有一个学生表,学生总数为 100 万人,男性只有 10 个人,也就是占总人口的 10 万分之 1 。
学生表 student_gender 结构如下。其中数据表中的 student_gender 字段取值为 0 或 1 , 0 代表女性, 1 代表男性。
一般来讲,数据重复度高于10%,就没有必要建立索引了
4.避免对经常更新的表创建过多的索引
第一层含义: 频繁更新的字段
不一定要创建索引。因为更新数据的时候,也需要更新索引,如果索引太多,在更新索引的时候也会造成负担,从而影响效率。
第二层含义: 避免对经常更新的表
创建过多的索引,并且索引中的列尽可能少。此时,虽然提高了查询速度,同时却会降低更新表的速度。
5.不建议用无序的值作为索引
例如身份证、UUID(在索引比较时需要转为ASCII,并且插入时可能造成页分裂
)、MD5、HASH、无序长字符串等。
6.删除不再使用或者很少使用的索引
表中的数据被大量更新,或者数据的使用方式被改变后,原有的一些索引可能不再需要。数据库管理员应当定期找出这些索引,将它们删除,从而减少索引对更新操作的影响。
7.不要定义冗余或重复的索引
① 冗余索引
举例:建表语句如下
CREATE TABLE person_info(
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
name VARCHAR( 100 ) NOT NULL,
birthday DATE NOT NULL,
phone_number CHAR( 11 ) NOT NULL,
country varchar( 100 ) NOT NULL,
PRIMARY KEY (id),
KEY idx_name_birthday_phone_number (name( 10 ), birthday, phone_number),
KEY idx_name (name( 10 ))
);
我们知道,通过idx_name_birthday_phone_number
索引就可以对name
列进行快速搜索,再创建一个专门针对name
列的索引就算是一个冗余索引
,维护这个索引只会增加维护的成本,并不会对搜索有什么好处。
② 重复索引
另一种情况,我们可能会对某个列重复建立索引
,比方说这样:
CREATE TABLE repeat_index_demo (
col1 INT PRIMARY KEY,
col2 INT,
UNIQUE uk_idx_c1 (col1),
INDEX idx_c1 (col1)
);
我们看到,col 1 既是主键、又给它定义为一个唯一索引,还给它定义了一个普通索引,可是主键本身就会生成聚簇索引,所以定义的唯一索引和普通索引是重复的,这种情况要避免。
2. 索引是一把双刃剑
索引是一把双刃剑
,可提高查询效率,但也会降低插入和更新的速度并占用磁盘空间。
选择索引的最终目的是为了使查询的速度变快,上面给出的原则是最基本的准则,但不能拘泥于上面的准则,在以后的学习和工作中进行不断的实践,根据应用的实际情况进行分析和判断,选择最合适的索引方式。