问题 1,
from a
left join b
on a.id=b.fid
where a.id=10
像这种是先 where 还是先 join? 还是数据库会根据它自己的判断进行优化?
问题 2,
select a.*,b.*
from a
left join b
on a.id=b.fid
order by a.id
limit 10
和
SELECT a1.*, b.*
FROM (
SELECT *
FROM a
ORDER BY a.id
LIMIT 10
) AS a1
LEFT JOIN b
ON a1.id = b.fid;
这两句话是不是执行效率是一样的?
你们在实际工作中遇到类似的场景多吗? 会纠结用哪种 sql 吗?
1
Ricebucket 84 天前
dba 会管这些?
|
2
GeekGao 84 天前
使用 EXPLAIN 查看 SQL 查询的执行计划,便知。通常会被自动优化。
假如 a 表 b 表很大,子查询这段 SQL 性能通常高一些,关键因素:LIMIT 。 对 LIMIT 解释: 在单表查询这段 SQL 中,LIMIT 位于 ORDER BY 之后,只取连接后排序后的前 10 条记录。 在子查询那段 SQL 中,LIMIT 位于子查询内部,只取 a 表排序后的前 10 条记录传递给外层查询。 |
3
levelworm 84 天前 via Android
Explain 一下就行了。一般优化的都很不错的。
|
4
a1b2c3T 84 天前
问题 1 应该是先 join 再 where
|
5
MozzieW 84 天前 1
@a1b2c3T 测试加上问 GPT ,至少在我有索引等情况下,会先执行 where 再 join 。下面是 GPT 的解释:
``` 理论上:SQL 语句的执行顺序是先 FROM 、再 JOIN 、最后 WHERE 过滤。 实际执行:数据库查询优化器可能会调整顺序,尽量减少数据处理的开销(比如尽可能早地应用 WHERE 过滤条件)。 ``` |
6
a1b2c3T 84 天前
@MozzieW #5 我记着前几年优化 sparksql 的时候这种问题还挺多的,那会儿一个优化点就是提前过滤表数据,可能数据库底层优化方式不一样吧。mysql 和 oracle 不知道会不会优化
|
7
MozzieW 84 天前
@a1b2c3T #6 是的,补充一下,我测试的是 MySql 。
这个属于具体的优化,不同的数据库实现不一样。 另外,这里只有一个主表的 where ,如果是多个表,结果可能不一样,不能理解为一定先执行 where 再执行 join |
8
andykuen959595 84 天前
这种 直接开跑起来 再看 要切合实际环境
|
9
qW7bo2FbzbC0 84 天前
1.按语法来说是 先 join 后 where
2.具体表格具体分析,看 explain 结果 |
10
xlzyxxn 84 天前
mysql 连接查询用的是嵌套循环算法,你这几个 sql 都是左连接或者右连接,驱动表和被驱动表已经确定了;你需要的是为每个表选择成本最低的访问方案;问题 1 问的没太懂,看看嵌套循环执行的步骤你可能就懂了;问题 2 第二种把驱动表缩小到了 10 条记录,扇出次数比第一种要少(在 mysql 没对第一种做优化的时候),效率肯定高,具体执行时 mysql 到底对第一种 sql 做没做优化这个就不清楚了
|
11
ZZ74 84 天前 1
|
12
sagaxu 84 天前 1
第一个问题,数据库一般会自己优化
https://dev.mysql.com/doc/refman/8.4/en/condition-filtering.html 第二个问题,第 2 个查询效率 >= 第 1 个,看 DB 的优化 |
13
kosmgco 84 天前
问题 1: 等值传递,优化器会拆成两个子查询 [from a where id = 10, from b where fid = 10],先 where 再 join 能少很多 io
问题 2:如果 a 数据量比较大,第二种方式左表的数据量会大大减少,会比第一种方式更快, 但是两种方式的结果不一样,第一种方式是先 join 再 order by 再 limit ,最终结果 10 条是确定的,第二种方式结果条数就不一定了 |
14
chaleaochexist OP |
15
chaleaochexist OP @ZZ74 第二个问题, 在实际开发过程中, 您会扣这种小细节还是选择相信数据库?
|
16
ZZ74 84 天前 1
我应该会直接用第二种写法,很可能第一种都不会出现在脑袋里。因为对我来说第二种更符合逻辑
|