postgresql 查询语句的执行顺序
PostgreSQL 查询语句的执行顺序遵循 SQL 标准的逻辑处理流程,但实际执行可能会因优化器的调整而有所不同。以下是其逻辑执行顺序的详细说明:
1. 逻辑执行顺序(编写顺序 vs 执行顺序)
SQL 语句的 编写顺序 通常是:
SELECT ...
FROM ...
WHERE ...
GROUP BY ...
HAVING ...
ORDER BY ...
LIMIT ...
但 实际逻辑执行顺序 为:
1. FROM 和 JOIN
2. WHERE
3. GROUP BY
4. HAVING
5. SELECT
6. DISTINCT
7. ORDER BY
8. LIMIT / OFFSET
2. 各阶段详解
(1) FROM 和 JOIN
o 作用:确定数据来源,加载表或子查询的数据,处理表之间的连接(JOIN)。 o 优先级:最先执行,生成初始数据集。 o 示例:
FROM table1
INNER JOIN table2 ON table1.id = table2.id
(2) WHERE
o 作用:过滤行数据,排除不满足条件的记录。 o 注意:无法在此阶段使用聚合函数(如 SUM, AVG)。 o 示例:
WHERE age > 18
(3) GROUP BY
o 作用:按指定列分组,通常与聚合函数配合使用。 o 示例:
GROUP BY department
(4) HAVING
o 作用:过滤分组后的结果(类似 WHERE,但用于分组后)。 o 注意:可在此阶段使用聚合函数。 o 示例:
HAVING SUM(sales) > 1000
(5) SELECT
o 作用:选择最终输出的列,计算表达式或聚合值。 o 注意:列别名在此阶段生效。 o 示例:
SELECT department, SUM(sales) AS total_sales
(6) DISTINCT
o 作用:去除重复行。 o 示例:
SELECT DISTINCT department
(7) ORDER BY
o 作用:对结果集排序。 o 注意:可使用 SELECT 中定义的别名。 o 示例:
ORDER BY total_sales DESC
(8) LIMIT / OFFSET
o 作用:限制返回的行数或跳过指定行。 o 示例:
LIMIT 10 OFFSET 5
3. 特殊场景与注意事项
(1) 子查询与 CTE(WITH 子句)
o 子查询:嵌套在 FROM、WHERE 或 SELECT 中的查询,其执行顺序依赖外层查询。 o CTE(公共表表达式):WITH 定义的临时表优先执行,但优化器可能合并到主查询中。
WITH cte AS (SELECT * FROM table1)
SELECT * FROM cte
(2) 窗口函数
o 执行时机:在 SELECT 阶段计算,但晚于 WHERE 和 GROUP BY。 o 示例:
SELECT name, salary, RANK() OVER (ORDER BY salary DESC)
(3) 集合操作(UNION, INTERSECT)
o 执行顺序:按语句顺序处理每个子查询,最后应用集合操作。
SELECT a FROM table1
UNION
SELECT b FROM table2
4. 示例演示
查询示例:
SELECT
department,
COUNT(*) AS employee_count
FROM employees
WHERE hire_date > '2020-01-01'
GROUP BY department
HAVING COUNT(*) > 5
ORDER BY employee_count DESC
LIMIT 3;
执行步骤:
- FROM employees:加载 employees 表。
- WHERE hire_date > '2020-01-01':过滤 2020 年后入职的员工。
- GROUP BY department:按部门分组。
- HAVING COUNT(*) > 5:筛选员工数超过 5 的部门。
- SELECT department, COUNT(*) AS employee_count:选择部门并计算员工数。
- ORDER BY employee_count DESC:按员工数降序排序。
- LIMIT 3:仅返回前 3 个部门。
5. 执行计划查看
通过 EXPLAIN 命令可查看 PostgreSQL 优化器生成的 实际执行计划,可能与逻辑顺序不同:
EXPLAIN ANALYZE
SELECT department, COUNT(*) FROM employees GROUP BY department;
输出示例:
GroupAggregate (cost=0.15..10.65 rows=5 width=15)
Group Key: department
-> Index Scan using idx_department on employees (cost=0.15..8.15 rows=1000 width=7)
总结
o 逻辑顺序:FROM → WHERE → GROUP BY → HAVING → SELECT → DISTINCT → ORDER BY → LIMIT.
o 实际执行:优化器可能调整顺序以提高性能(如使用索引跳过某些步骤)。
o 关键点:理解逻辑顺序有助于编写高效查询,但需结合 EXPLAIN 分析实际执行行为。
本文暂时没有评论,来添加一个吧(●'◡'●)