searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

SQL索引使用原则

2024-10-10 02:06:59
0
0

索引是数据库中用于加速数据检索的数据结构,它可以让数据库系统不必扫描全表,而是直接定位到满足条件的记录,从而大大减少查询时间和资源消耗。TiDB支持主键索引、唯一索引、普通索引和前缀索引等多种类型的索引,用户可以根据实际业务需求来创建合适的索引。

 

但是,并不是所有的字段都适合建立索引,也不是索引越多越好。过多或不合理的索引会增加数据维护的开销,降低数据更新和插入的速度,占用更多的存储空间,甚至导致查询优化器选择错误的执行计划。

 

一、哪些情况适合建立索引

1. 字段的数值有唯一性的限制,比如用户名

索引本身可以起到约束的作用,比如唯一索引、主键索引都是可以起到唯一性约束的,因此在我们的数据表中,如果某个字段是唯一性的,就可以直接创建唯一性索引,或者主键索引。

 

2. 频繁作为 WHERE 查询条件的字段,尤其在数据表大的情况下

在数据量大的情况下,某个字段在 SQL 查询的 WHERE 条件中经常被使用到,那么就需要给这个字段创建索引了。创建普通索引就可以大幅提升数据查询的效率。

 

3. 需要经常 GROUP BY ORDER BY 的列

索引就是让数据按照某种顺序进行存储或检索,因此当我们使用 GROUP BY 对数据进行分组查询,或者使用 ORDER BY 对数据进行排序的时候,就需要对分组或者排序的字段进行索引。

 

4. UPDATEDELETE WHERE 条件列,一般也需要创建索引

对数据按照某个条件进行查询后再进行 UPDATE DELETE 的操作,如果对 WHERE 字段创建了索引,就能大幅提升效率。原理是因为我们需要先根据 WHERE 条件列检索出来这条记录,然后再对它进行更新或删除。如果进行更新的时候,更新的字段是非索引字段,提升的效率会更明显,这是因为非索引字段更新不需要对索引进行维护。

不过在实际工作中,我们也需要注意平衡,如果索引太多了,在更新数据的时候,如果涉及到索引更新,就会造成负担。

 

5. DISTINCT 字段需要创建索引

有时候我们需要对某个字段进行去重,使用 DISTINCT,那么对这个字段创建索引,也会提升查询效率。

 

6. 做多表 JOIN 连接操作时,创建索引需要注意以下的原则

首先,连接表的数量尽量不要超过 3 张,因为每增加一张表就相当于增加了一次嵌套的循环,数量级增长会非常快,严重影响查询的效率。

其次,对 WHERE 条件创建索引,因为 WHERE 才是对数据条件的过滤。如果在数据量非常大的情况下,没有 WHERE 条件过滤是非常可怕的。

最后,对用于连接的字段创建索引,并且该字段在多张表中的类型必须一致。比如 user_id product_comment 表和 user 表中都为 int(11) 类型,而不能一个为 int 另一个为 varchar 类型。

 

二、什么时候不需要创建索引

1. WHERE 条件(包括 GROUP BYORDER BY)里用不到的字段不需要创建索引,索引的价值是快速定位,如果起不到定位的字段通常是不需要创建索引的。

2. 字段中如果有大量重复数据,也不用创建索引

3. 频繁更新的字段不一定要创建索引。因为更新数据的时候,也需要更新索引,如果索引太多,在更新索引的时候也会造成负担,从而影响效率。

 

 

三、什么情况下索引失效

1. 如果索引进行了表达式计算,则会失效

2. 如果对索引使用函数,也会造成失效

3. WHERE 子句中,如果在 OR 前的条件列进行了索引,而在 OR 后的条件列没有进行索引,那么索引会失效。

4. 当我们使用 LIKE 进行模糊查询的时候,后面不能是 %

5. 索引列与 NULL 或者 NOT NULL 进行判断的时候也会失效。

6. 我们在使用联合索引的时候要注意最左原则

 

四、SQL编写原则

1. 尽量使用预编译语句或参数化语句,而不是拼接字符串来生成动态SQL语句,这样可以避免SQL注入攻击,提高SQL执行效率,减少SQL解析开销。

2. 尽量避免使用SELECT *来查询所有列,而是只查询需要的列,这样可以减少网络传输和内存占用,提高查询速度。

3. 尽量避免使用子查询,而是使用JOINEXISTS等关联查询方式,这样可以减少查询层次,简化查询逻辑,提高查询效率。

4. 尽量避免使用UNION ALL来合并多个子查询的结果,而是使用JOINEXISTS等关联查询方式,这样可以减少数据冗余,提高查询效率。

5. 尽量避免使用ORDER BYGROUP BYDISTINCT等排序和去重操作,或者在使用时尽量利用索引来进行排序和去重,这样可以减少排序和去重的开销,提高查询效率。

6. 尽量避免使用HAVING子句来过滤分组后的结果,而是在WHERE子句中进行过滤,这样可以减少分组后的数据量,提高查询效率。

7. 尽量避免使用LIMIT子句来分页查询数据,而是使用索引列和条件过滤来实现分页功能,这样可以减少扫描的数据量,提高查询效率。

0条评论
0 / 1000
l****n
4文章数
0粉丝数
l****n
4 文章 | 0 粉丝
l****n
4文章数
0粉丝数
l****n
4 文章 | 0 粉丝
原创

SQL索引使用原则

2024-10-10 02:06:59
0
0

索引是数据库中用于加速数据检索的数据结构,它可以让数据库系统不必扫描全表,而是直接定位到满足条件的记录,从而大大减少查询时间和资源消耗。TiDB支持主键索引、唯一索引、普通索引和前缀索引等多种类型的索引,用户可以根据实际业务需求来创建合适的索引。

 

但是,并不是所有的字段都适合建立索引,也不是索引越多越好。过多或不合理的索引会增加数据维护的开销,降低数据更新和插入的速度,占用更多的存储空间,甚至导致查询优化器选择错误的执行计划。

 

一、哪些情况适合建立索引

1. 字段的数值有唯一性的限制,比如用户名

索引本身可以起到约束的作用,比如唯一索引、主键索引都是可以起到唯一性约束的,因此在我们的数据表中,如果某个字段是唯一性的,就可以直接创建唯一性索引,或者主键索引。

 

2. 频繁作为 WHERE 查询条件的字段,尤其在数据表大的情况下

在数据量大的情况下,某个字段在 SQL 查询的 WHERE 条件中经常被使用到,那么就需要给这个字段创建索引了。创建普通索引就可以大幅提升数据查询的效率。

 

3. 需要经常 GROUP BY ORDER BY 的列

索引就是让数据按照某种顺序进行存储或检索,因此当我们使用 GROUP BY 对数据进行分组查询,或者使用 ORDER BY 对数据进行排序的时候,就需要对分组或者排序的字段进行索引。

 

4. UPDATEDELETE WHERE 条件列,一般也需要创建索引

对数据按照某个条件进行查询后再进行 UPDATE DELETE 的操作,如果对 WHERE 字段创建了索引,就能大幅提升效率。原理是因为我们需要先根据 WHERE 条件列检索出来这条记录,然后再对它进行更新或删除。如果进行更新的时候,更新的字段是非索引字段,提升的效率会更明显,这是因为非索引字段更新不需要对索引进行维护。

不过在实际工作中,我们也需要注意平衡,如果索引太多了,在更新数据的时候,如果涉及到索引更新,就会造成负担。

 

5. DISTINCT 字段需要创建索引

有时候我们需要对某个字段进行去重,使用 DISTINCT,那么对这个字段创建索引,也会提升查询效率。

 

6. 做多表 JOIN 连接操作时,创建索引需要注意以下的原则

首先,连接表的数量尽量不要超过 3 张,因为每增加一张表就相当于增加了一次嵌套的循环,数量级增长会非常快,严重影响查询的效率。

其次,对 WHERE 条件创建索引,因为 WHERE 才是对数据条件的过滤。如果在数据量非常大的情况下,没有 WHERE 条件过滤是非常可怕的。

最后,对用于连接的字段创建索引,并且该字段在多张表中的类型必须一致。比如 user_id product_comment 表和 user 表中都为 int(11) 类型,而不能一个为 int 另一个为 varchar 类型。

 

二、什么时候不需要创建索引

1. WHERE 条件(包括 GROUP BYORDER BY)里用不到的字段不需要创建索引,索引的价值是快速定位,如果起不到定位的字段通常是不需要创建索引的。

2. 字段中如果有大量重复数据,也不用创建索引

3. 频繁更新的字段不一定要创建索引。因为更新数据的时候,也需要更新索引,如果索引太多,在更新索引的时候也会造成负担,从而影响效率。

 

 

三、什么情况下索引失效

1. 如果索引进行了表达式计算,则会失效

2. 如果对索引使用函数,也会造成失效

3. WHERE 子句中,如果在 OR 前的条件列进行了索引,而在 OR 后的条件列没有进行索引,那么索引会失效。

4. 当我们使用 LIKE 进行模糊查询的时候,后面不能是 %

5. 索引列与 NULL 或者 NOT NULL 进行判断的时候也会失效。

6. 我们在使用联合索引的时候要注意最左原则

 

四、SQL编写原则

1. 尽量使用预编译语句或参数化语句,而不是拼接字符串来生成动态SQL语句,这样可以避免SQL注入攻击,提高SQL执行效率,减少SQL解析开销。

2. 尽量避免使用SELECT *来查询所有列,而是只查询需要的列,这样可以减少网络传输和内存占用,提高查询速度。

3. 尽量避免使用子查询,而是使用JOINEXISTS等关联查询方式,这样可以减少查询层次,简化查询逻辑,提高查询效率。

4. 尽量避免使用UNION ALL来合并多个子查询的结果,而是使用JOINEXISTS等关联查询方式,这样可以减少数据冗余,提高查询效率。

5. 尽量避免使用ORDER BYGROUP BYDISTINCT等排序和去重操作,或者在使用时尽量利用索引来进行排序和去重,这样可以减少排序和去重的开销,提高查询效率。

6. 尽量避免使用HAVING子句来过滤分组后的结果,而是在WHERE子句中进行过滤,这样可以减少分组后的数据量,提高查询效率。

7. 尽量避免使用LIMIT子句来分页查询数据,而是使用索引列和条件过滤来实现分页功能,这样可以减少扫描的数据量,提高查询效率。

文章来自个人专栏
专栏文章
4 文章 | 1 订阅
0条评论
0 / 1000
请输入你的评论
0
0