SQL 性能优化介绍

发布于 2024-03-25 05:46:23 字数 2951 浏览 51 评论 0

使用高效的查询

参数是子查询时,使用 EXISTS 代替 IN。

-- 慢
SELECT *
FROM Class_A
WHERE id IN (SELECT id FROM Class_B);
-- 快
SELECT *
FROM Class_A A
WHERE EXISTS
    (SELECT *
    FROM Class_B B
    WHERE A.id = B.id);

使用 EXISTS 时更快的原因有以下两个。

  • 如果连接列(id)上建立了索引,那么查询 Class_B 时不用查实际的表,只需查索引。
  • 如果使用 EXISTS,那么只要查到一行数据满足条件就会终止查询,
    不用像使用 IN 时一样扫描全表。在这一点上 NOT EXISTS 也一样。

当 IN 的参数是子查询时,数据库首先会执行子查询,将结果存储在一张临时的工作表里(内联视图),然后扫描整个视图。这种做法非常耗费资源。

使用 EXISTS 的话,数据库不会生成临时的工作表。

参数是子查询时,使用连接代替 IN。

-- 使用连接代替 IN
SELECT A.id, A.name
FROM Class_A A INNER JOIN Class_B B
ON A.id = B.id;

避免排序

会进行排序的代表性的运算有下面这些。

  • GROUP BY 子句
  • ORDER BY 子句
  • 聚合函数(SUM、COUNT、AVG、MAX、MIN)
  • DISTINCT
  • 集合运算符(UNION、INTERSECT、EXCEPT)
  • 窗口函数(RANK、ROW_NUMBER 等)

灵活使用集合运算符的 ALL

如果不在乎结果中是否有重复数据,或者事先知道不会有重复数据,
使用 UNION ALL 代替 UNION。

SELECT * FROM Class_A
UNION ALL
SELECT * FROM Class_B;

使用 EXISTS 代替 DISTINCT

SELECT DISTINCT I.item_no
FROM Items I INNER JOIN SalesHistory SH
ON I. item_no = SH. item_no;

被替换为

SELECT item_no
FROM Items I
WHERE EXISTS
    (SELECT *
    FROM SalesHistory SH
    WHERE I.item_no = SH.item_no);

这条语句在执行过程中不会进行排序。

极值函数中使用索引(MAX/MIN)

SELECT MAX(some_index)
FROM Items;

能写在 WHERE 子句里的条件不写在 HAVING 子句

在使用 GROUP BY 子句聚合时会进行排序,如果事先通过 WHERE 子句筛选出一部分行,就能减轻排序的负担。

在 WHERE 子句的条件里可以使用索引。HAVING 子句是针对聚合后生成的视图进行筛选的,
但很多时候聚合后的视图都没有继承原表的索引结构。

GROUP BY 和 ORDER BY 子句中使用索引

正确利用索引

在索引字段上进行运算

WHERE col_1 * 1.1 > 100 -- 无法利用索引
WHERE col_1 > 100 / 1.1 -- 高效做法

使用索引时,条件表达式的左侧应该是原始字段。

减少中间表

灵活使用 HAVING 子句

SELECT *
FROM (SELECT sale_date, MAX(quantity) AS max_qty
        FROM SalesHistory
        GROUP BY sale_date) TMP -- 中间表
WHERE max_qty >= 10;
SELECT sale_date, MAX(quantity)
FROM SalesHistory
GROUP BY sale_date
HAVING MAX(quantity) >= 10;

HAVING 子句和聚合操作同时执行,比起生成中间表后再执行的 WHERE 子句,效率会更高。

合理使用视图

视图的定义语句中包含以下运算的时,SQL 会非常低效。

  • 聚合函数(AVG、COUNT、SUM、MIN、MAX)
  • 集合运算符(UNION、INTERSECT、EXCEPT 等)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

捎一片雪花

暂无简介

文章
评论
27 人气
更多

推荐作者

櫻之舞

文章 0 评论 0

弥枳

文章 0 评论 0

m2429

文章 0 评论 0

野却迷人

文章 0 评论 0

我怀念的。

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文