U2647's blog 一个热爱学习的 Java 程序员,喜欢 Vue,喜欢深度学习 Dubbo Flutter SpringBoot Debug Notes Java LeetCode Python Redis Android DesignPattern mdi-home-outline 首页 mdi-cloud-outline 标签云 mdi-timeline-text-outline 时间轴 mdi-draw-pen 文章总数 62
SQL 性能优化的几条建议 SQL 性能优化的几条建议 SQL SQL 性能优化 mdi-cursor-default-click-outline 点击量 62

1. 避免使用外键

使用外键时会使锁升级,并行度下降。例如,不使用外键的时候,只需要锁一张表,当使用外键后,需要锁两张表。

2. 将 DISTINCT 值较高的字段设置为索引

DISTINCT 值是指去重后的数量,这个数量越大,说明字段的值重复率越低,索引效果就越好。

3. 将表关联时被关联的字段设置为索引

将被关联的字段设置为索引,可以提高关联表的效率

4. 调整复合索引的字段顺序

  • 将 DISTINCT 值较高的字段设置为前导字段。
  • 如果 DISTINCT 值相近,将频繁查询的字段往前调。
  • 如果查询频率相近,将排序字段往前调。

避免出现 索引跳跃式扫描(index skip sacn)

例如:我们有一张订单表,我们对订单号、订单状态做了复合索引。但是,索引创建的时候是订单状态列在前,订单号在后。如果我们要根据一个订单号查询时,Oracle 会先在状态 A 中的订单里查该订单,然后在状态 B 中查该订单,以此类推,当在所有的状态中查询结束后合并结果,就是最终的结果,这种情况就是 索引跳跃式扫描。

5. 索引字段尽量避免 NULL 值

  • 在 Oracle 中索引里含有 NULL 值会导致索引失效
  • 在 MySQL 中索引里含有 NULL 会导致额外的存储开销

6. 尽量避免大事务,超出 UNDO 表空间

UNDO 表空间:在执行事务时,会将参与事务的数据备份到 UNDO 表空间,解决读一致问题。

如果事务操作的数据量过大,会可能撑爆 UNDO 表空间

7. SELECT、INSERT 语句要写清楚列名

如果不写清楚列名,数据库会先查询一次列名。影响 SQL 的执行时间

8. 用 EXISTS 代替 IN

IN 是把外表和内表作hash join,而 EXISTS 是对外表做 loop,每次 loop 再对内表进行查询。

9. LIKE 使用前端匹配

使用 LIKE ‘%xxx’,尽量避免使用 LIKE ‘%xxx%’,这种会导致索引失效

10. 尽可能用 UNION ALL 代替 UNION

UNION 会对结果进行去重,影响查询效率

11. 左外连接时,尽可能限制左表的数据量

左表的数据量越小,查询结果就越小。

尽量避免笛卡尔积的情况出现

版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!
我的GitHub 我的LeetCode 我的掘金
Powered by Hexo Powered by three-cards
Copyright © 2017 - {{ new Date().getFullYear() }} 某ICP备xxxxxxxx号