gpt4 book ai didi

sql - 为什么子查询和join这么慢

转载 作者:行者123 更新时间:2023-12-02 19:45:08 26 4
gpt4 key购买 nike

我需要从 BUNDLES 表中选择具有多个 SAP_STATE_ID 值之一的行。这些值取决于是否应导出相应的 SAP 状态。

这个查询运行得非常快(SAP_STATE_ID 字段上有索引)-

SELECT b.* FROM BUNDLES b WHERE b.SAP_STATE_ID IN (2,3,5,6)

但是...我想动态获取 ID 列表,如下所示:

SELECT b.* FROM BUNDLES b 
WHERE b.SAP_STATE_ID IN
(SELECT s.SAP_STATE_ID FROM SAP_STATES s WHERE s.EXPORT_TO_SAP = 1)

哎哟,这个查询突然花费了太多时间。我希望 SQL Server 首先运行子查询(它不依赖于主查询中的任何内容),然后像我的第一个示例一样运行整个查询。我尝试重写它以使用联接而不是子查询:

SELECT b.* FROM BUNDLES b 
JOIN SAP_STATES s ON (s.SAP_STATE_ID = b.SAP_STATE_ID)
WHERE s.EXPORT_TO_SAP = 1

但它的性能同样较差。看起来它正在为 BUNDLES 表的每一行运行子查询或类似的东西。我不太擅长阅读执行计划,但我尝试过。它说81%的成本用于扫描BUNDLES的主键索引(我不知道为什么它应该做这样的事情,有BUNDLE_ID字段定义为PRIMARY KEY,但它根本没有出现在查询中...... )

有谁能解释一下为什么 SQL Server 如此“愚蠢”吗?有没有办法以良好的性能实现我想要的目标,但不需要提供 SAP_STATE_ID 的静态列表?

表和相关索引的脚本 - http://mab.to/xbYiI0wKj

子查询版本的执行计划 - http://mab.to/8Qh6gpdYZ

带有连接的版本的查询计划 - http://mab.to/YCqeGCUbr

(出于某种原因,这两个计划看起来相同,并且都建议创建 BUNDLES.SAP_STATE_ID 索引,该索引已经存在)

最佳答案

我很确定你的统计数据不正确。如果您想让它快速工作,我会将查询编写为:

SELECT b.*
FROM SAP_STATES s
INNER LOOP JOIN BUNDLES b
ON s.SAP_STATE_ID = b.SAP_STATE_ID
WHERE s.EXPORT_TO_SAP = 1

这会强制在SAP_STATES上进行嵌套循环连接,该循环会在BUNDLES上进行过滤

关于sql - 为什么子查询和join这么慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26124524/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com