gpt4 book ai didi

sql-server - 这些使用 OR 的 T-SQL 查询有什么区别?

转载 作者:行者123 更新时间:2023-12-02 13:51:23 24 4
gpt4 key购买 nike

我使用 Microsoft SQL Server 2008(SP1,x64)。我有两个查询执行相同的操作,或者我认为是这样,但它们具有完全不同的查询计划和性能。

查询1:

SELECT c_pk
FROM table_c
WHERE c_b_id IN (SELECT b_id FROM table_b WHERE b_z = 1)
OR c_a_id IN (SELECT a_id FROM table_a WHERE a_z = 1)

查询2:

SELECT c_pk
FROM table_c
LEFT JOIN (SELECT b_id FROM table_b WHERE b_z = 1) AS b ON c_b_id = b_id
LEFT JOIN (SELECT a_id FROM table_a WHERE a_z = 1) AS a ON c_a_id = a_id
WHERE b_id IS NOT NULL
OR a_id IS NOT NULL

查询 1 的速度如我所料,而查询 2 的速度非常慢。 query plans看起来很不一样。

我希望查询 2 与查询 1 一样快。我有使用查询 2 的软件,但我无法将其更改为查询 1。我可以更改数据库。

一些问题:

  • 为什么查询计划不同?
  • 我可以以某种方式“教导”SQL Server 查询 2 等于查询 1 吗?

所有表在所有列上都有(聚集)主键和适当的索引:

CREATE TABLE table_a (
a_pk int NOT NULL PRIMARY KEY,
a_id int NOT NULL UNIQUE,
a_z int
)
GO
CREATE INDEX IX_table_a_z ON table_a (a_z)
GO

CREATE TABLE table_b (
b_pk int NOT NULL PRIMARY KEY,
b_id int NOT NULL UNIQUE,
b_z int
)
GO
CREATE INDEX IX_table_b_z ON table_b (b_z)
GO

CREATE TABLE table_c (
c_pk int NOT NULL PRIMARY KEY,
c_a_id int,
c_b_id int
)
GO
CREATE INDEX IX_table_c_a_id ON table_c (c_a_id)
GO
CREATE INDEX IX_table_c_b_id ON table_c (c_b_id)
GO

表格在最初填写后不会被修改。我是唯一一个询问他们的人。它们包含数百万条记录(table_a:5M、table_b:4M、table_c:12M),但仅使用 1% 即可得到相似的结果。

编辑:我尝试为 c_a_idc_b_id 添加外键,但这只会使查询 1 变慢...

我希望有人可以看看query plans并解释其中的差异。

最佳答案

加入速度较慢,是设计使然。第一个查询使用子查询(可缓存)来过滤记录,因此它将产生更少的数据(以及对每个表的更少访问)。

你读过这些吗:

我的意思是,通过 IN,数据库可以进行更好的优化,例如删除重复项、在第一个匹配处停止等类似的操作(这些来自学校内存,所以我'我确信它会做得更好)。因此,我猜测问题不在于 QP 为何不同,而在于优化的深度有多智能。

关于sql-server - 这些使用 OR 的 T-SQL 查询有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9683342/

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