数据库中子查询是什么,能否详细解释其概念?
- 内容介绍
- 文章标签
- 相关推荐
怎么说呢,


什么是子查询?
子查询的类型
1. SELECT 子句中的子查询
用于返回派生列或计算值,例如:
SELECT column_name
FROM table_name
WHERE column_name = (
SELECT column_name
FROM table_name
WHERE condition
);按理说,
2. FROM 子句中的子查询
创建一个临时表作为外部查询的数据源:
SELECT t.column_name
FROM (
SELECT column_name
FROM table_name
WHERE condition
) AS subquery t;
3. WHERE 子句中的子查询
用于设置过滤条件,常见写法有 =,IN。EXISTS 等:
4. HING 子句中的子查询
在分组过滤时使用:
5. INSERT INTO / UPDATE / DELETE 语句中的子查询
- INSERT INTO:将内部查询结果插入目标表。
- UPDATE:利用子查询更新满足特定条件的记录。
- DELETE:通过子查询定位并删除符合条件的数据。
为什么要使用子查询?——使用者痛点与价值点对接
- Pain Point 1:数据过滤不精准导致业务异常。 使用子查询可以在数据库层面完成精确过滤,避免在业务层做大量数据遍历。怎么说呢,
- Pain Point 2:SQL 代码冗长难维护。 子查询结构让 SQL 更简洁。可读性提高,后期维护成本下降。
- Pain Point 3:复杂业务需求频繁出现,需要跨表关联或多层聚合。 多层嵌套的子查询能够一次性完成跨表计算,降低多次 round‑trip 的网络开销。
- Pain Point 4:性能担忧——执行多个嵌套查询是否会拖慢程序?
性能痛点与调整建议
Pain Point: 子查询需要执行多个独立的 SQL 语句。如果写得不当,会导致全表扫描、临时表溢出或索引失效,从而显著降低响应速度。
1️⃣ 调整思路概览
-
#尽量使用 JOIN 替代非相关子查询 - 等价的
可以让调整器直接利用索引; - #限制返回列数 - 只取必要字段,避免产生宽大的临时结果集;
- #为内部 query 添加合适索引 - 确保内部筛选条件走索引;
- #避免深度嵌套 - 超过两层以上的嵌套往往难以调整,考虑拆分为临时表或 CTE;
- #使用 EXISTS/NOT EXISTS 替代 IN/NOT IN - 当内部集合很大时EXISTS 的短路特性更高效;
-
#利用数据库统计信息和执行计划 - 查看
,找到“全表扫描”或“临时文件排序”等瓶颈。
2️⃣ 常见性能陷阱示例 & 方案
| 不佳写法 | 推荐 方式 |
|---|
// 非相关子查询 + IN,内部返回大量记录
SELECT *
FROM orders o
WHERE o.customer_id IN (
SELECT c.id
FROM customers c
WHERE c.status = 'ACTIVE'
);
// 使用 JOIN + 索引,避免生成大列表再匹配
SELECT o.*
FROM orders o
JOIN customers c ON o.customer_id = c.id
WHERE c.status = 'ACTIVE';其实,
// 深度嵌套导致临时表生成
SELECT *
FROM products p
WHERE p.id IN (
SELECT productid
FROM orderitems
WHERE orderid IN (
SELECT id FROM orders WHERE createdat> '2024-01-01'
)
);
// 使用 CTE 或先建临时结果集,再一次 JOIN
WITH recentorders AS (
SELECT id FROM orders WHERE createdat> '2024-01-01'
)
SELECT p.*
FROM products p
JOIN orderitems oi ON p.id = oi.productid
JOIN recentorders ro ON oi.orderid = ro.id;
// MySQL 可改为两次 JOIN,同理减少嵌套层数。
...
怎么说呢,


什么是子查询?
子查询的类型
1. SELECT 子句中的子查询
用于返回派生列或计算值,例如:
SELECT column_name
FROM table_name
WHERE column_name = (
SELECT column_name
FROM table_name
WHERE condition
);按理说,
2. FROM 子句中的子查询
创建一个临时表作为外部查询的数据源:
SELECT t.column_name
FROM (
SELECT column_name
FROM table_name
WHERE condition
) AS subquery t;
3. WHERE 子句中的子查询
用于设置过滤条件,常见写法有 =,IN。EXISTS 等:
4. HING 子句中的子查询
在分组过滤时使用:
5. INSERT INTO / UPDATE / DELETE 语句中的子查询
- INSERT INTO:将内部查询结果插入目标表。
- UPDATE:利用子查询更新满足特定条件的记录。
- DELETE:通过子查询定位并删除符合条件的数据。
为什么要使用子查询?——使用者痛点与价值点对接
- Pain Point 1:数据过滤不精准导致业务异常。 使用子查询可以在数据库层面完成精确过滤,避免在业务层做大量数据遍历。怎么说呢,
- Pain Point 2:SQL 代码冗长难维护。 子查询结构让 SQL 更简洁。可读性提高,后期维护成本下降。
- Pain Point 3:复杂业务需求频繁出现,需要跨表关联或多层聚合。 多层嵌套的子查询能够一次性完成跨表计算,降低多次 round‑trip 的网络开销。
- Pain Point 4:性能担忧——执行多个嵌套查询是否会拖慢程序?
性能痛点与调整建议
Pain Point: 子查询需要执行多个独立的 SQL 语句。如果写得不当,会导致全表扫描、临时表溢出或索引失效,从而显著降低响应速度。
1️⃣ 调整思路概览
-
#尽量使用 JOIN 替代非相关子查询 - 等价的
可以让调整器直接利用索引; - #限制返回列数 - 只取必要字段,避免产生宽大的临时结果集;
- #为内部 query 添加合适索引 - 确保内部筛选条件走索引;
- #避免深度嵌套 - 超过两层以上的嵌套往往难以调整,考虑拆分为临时表或 CTE;
- #使用 EXISTS/NOT EXISTS 替代 IN/NOT IN - 当内部集合很大时EXISTS 的短路特性更高效;
-
#利用数据库统计信息和执行计划 - 查看
,找到“全表扫描”或“临时文件排序”等瓶颈。
2️⃣ 常见性能陷阱示例 & 方案
| 不佳写法 | 推荐 方式 |
|---|
// 非相关子查询 + IN,内部返回大量记录
SELECT *
FROM orders o
WHERE o.customer_id IN (
SELECT c.id
FROM customers c
WHERE c.status = 'ACTIVE'
);
// 使用 JOIN + 索引,避免生成大列表再匹配
SELECT o.*
FROM orders o
JOIN customers c ON o.customer_id = c.id
WHERE c.status = 'ACTIVE';其实,
// 深度嵌套导致临时表生成
SELECT *
FROM products p
WHERE p.id IN (
SELECT productid
FROM orderitems
WHERE orderid IN (
SELECT id FROM orders WHERE createdat> '2024-01-01'
)
);
// 使用 CTE 或先建临时结果集,再一次 JOIN
WITH recentorders AS (
SELECT id FROM orders WHERE createdat> '2024-01-01'
)
SELECT p.*
FROM products p
JOIN orderitems oi ON p.id = oi.productid
JOIN recentorders ro ON oi.orderid = ro.id;
// MySQL 可改为两次 JOIN,同理减少嵌套层数。
...

