索引的优缺点
优势
- 提高数据检索的效率
- 通过索引列对数据进行排序,降低数据排序的成本
劣势
- 索引列也是要占用空间的
- 索引大大提高了查询效率,同时却也降低更新表的速度,如对表进行INSERT、UPDATE、DELETE时
不建立索引的情况
数据量小的表最好不要使用索引:如果表记录太少,比如少于1000个,那么是不需要创建索引的。表记录太少,是否创建索引对查询效率的影响并不大。甚至说,查询花费的时间可能比遍历索引的时间还要短,索引可能不会产生优化效果。
MySQL中,一张数据库表中记录数量小于 300 万条时,即使创建索引也不会让搜索速度有明显提升。
在where中使用不到的字段,不要设置索引:WHERE条件(包括GROUP BY、ORDER BY)里用不到的字段不需要创建索引,索引的价值是快速定位,如果起不到定位的字段通常是不需要创建索引的。
有大量重复数据的列上不要建立索引:如,status和性别
经常增删改的表,建立索引提高了查询速度,同时却会降低更新表的速度,如对表进行 INSERT、UPDATE 和 DELETE。因为更新表时,MySQL 不仅要保存数据,还要保存一下索引文件,重新排布索引,这个操作需要对索引表做全表扫描。不仅索引表的全表扫描操作本身非常耗时,而且索引重新排布时不可用,此时执行查询操作没有索引可用,还是要回到原始数据库表做全表扫描。
避免对经常更新的表创建过多的索引
- 频繁
更新的字段
不一定要创建索引。因为更新数据的时候,也需要更新索引,如果索引太多,在更新索引的时候也会造成负担,从而影响效率。 - 避免对
经常更新的表
创建过多的索引,并且索引中的列尽可能少。此时,虽然提高了查询速度,同时却会降低更新表的速度。
- 频繁
不建议用无序的值作为索引:例如身份证、UUID(在索引比较时需要转为ASCII,并且插入时可能造
成页分裂
)、MD5、HASH、无序长字符串等。不要定义冗余或重复的索引:
- 冗余索引
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 既是主键、又给它定义为一个唯一索引,还给它定义了一个普通索引,可是主键本身就会生成聚簇索引,所以定义的唯一索引和普通索引是重复的,这种情况要避免。
哪些字段时候做索引
- 针对于数据量较大,且查询比较频繁的表建立索引。
- 针对于常作为查询条件(where)、排序(order by)、分组(group by)操作的字段建立索引。
- 尽量选择区分度高的列作为索引,尽量建立唯一索引,区分度越高,使用索引的效率越高。
- 下列情况创建索引效果更好
- 字段的数值有唯一性限制
- 类型小的字段
- 如果是字符串类型的字段,字段的长度较长,可以针对于字段的特点,建立前缀索引。
- 尽量使用联合索引,减少单列索引,查询时,联合索引很多时候可以覆盖索引,节省存储空间,避免回表,提高查询效率。
- 如果索引列不能存储NULL值,请在创建表时使用NOT NULL约束它。当优化器知道每列是否包含NULL值时,它可以更好地确定哪个索引最有效地用于查询。
- 要控制索引的数量,索引并不是多多益善,索引越多,维护索引结构的代价也就越大,会影响增删改的效率。
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 1909773034@qq.com