一. 建立索引简述
- 索引通常分为聚集索引和非聚集索引。
- 聚集索引速度很快,但只能建一个,所以尽量把经常使用的列建成聚集索引。
- 非聚集索引虽然没聚集索引快,但可以建多个,比全表扫描快。
二. 如何建立高效的索引
-
经常作为条件查询(where)的列适合建立索引
-
重复数据较少的可以建立索引
-
不频繁插入和更新的列适合建立索引
-
经常需要排序(order)、分组(group by)的字段适合建立索引
-
连表查询的关联条件(on)列可以建立索引
select * from tableA left join on tableB on tableA.name = tableB.p_name;
划重点:在关联条件ON后面的两个列分别建立索引,可以很快将符合关联条件的数据查询出来。
-
如果索引字段的值很长,最好使用值的前缀来建立索引
例如,TEXT 和 BLOG 类型的字段进行全文检索时很浪费时间。如果只检索字段的前面的若干个字符,可以提高检索速度。
-
限制索引的数目。索引的数目不是越多越好。
原因:
(1)每个索引都需要占用磁盘空间,索引越多,需要的磁盘空间就越大
(2)修改表时,对索引的重构和更新很麻烦。越多的索引,会使更新表变得很浪费时间。 -
定期删除不再使用或者很少使用的索引
当表中的数据被大量更新,或者数据的使用方式被改变后,原有的一些索引可能不再需要。
因此数据库管理员应当定期找出这些索引,将它们删除,从而减少索引对更新操作的影响。 -
连表查询时,尽量少join表,因为可能会造成笛卡尔积的恐怖扫描;尽量使用left join,并且以少关联多。因为使用left join的第一张表是全扫描的,以少关联多就可以减少这个扫描次数。
三. 不走索引的SQL
-
没有查询条件,或者查询条件没有索引
-
查询的结果占总数据的 15% 以上
-
在索引列上使用了运算符。
例如:
where age*2>10
,或where id-1=1
。 -
在索引列上使用了函数。
例如:
where UPPER(name)='MAOMI'
。 -
索引列条件为NULL。
例如:
where name IS NULL或name is not null
。 -
字符型数据不加引号。
例如:ent_id是字符型,
where ent_id='123456'
会使用索引;但如果去掉引号,变成了ent_id=123456
,查询语句不会报错,但不会走索引。 -
或(OR)、不等(<>,!=)、NOT IN等不会走索引。
-
LIKE条件,除了前置匹配走索引,其他匹配均不走索引。例如:
name LIKE ‘NEW%’
会走索引,但是像name LIKE ‘%NEW%’
和name LIKE ‘%NEW’
均不走索引。 -
如果查询优化器判断,全表扫描比走索引还快也不会走索引。
-
联合索引的顺序不符合最左前缀原则。