gpt4 book ai didi

sql-server - 使用条件连接语句时执行多个全索引扫描

转载 作者:行者123 更新时间:2023-12-02 05:00:01 25 4
gpt4 key购买 nike

我在查询具有父/子关系行的表时遇到问题。在编写一个简化示例时,我意识到 stackexchange 架构非常相似。

假设我正在通过 stackexchange 数据资源管理器查询 stackoverflow posts 表。我正在尝试获取所有帖子的子集及其相关答案。

参见 https://data.stackexchange.com/stackoverflow/query/121981/a-subset-of-questions-and-associated-answers示例查询。

帖子的子集是在一个 View 中定义的,它有一个相当复杂和昂贵的查询计划。在下面的示例中,它已被简化为只需选择前两行。

第一种方式,使用联合:

with ExpensiveView as (select top 2 ID from Posts order by ID)

select Posts.*
from ExpensiveView
left outer join Posts
ON ExpensiveView.Id = Posts.Id

union all

select Posts.*
from ExpensiveView
left outer join Posts
ON ExpensiveView.Id = Posts.ParentId

我很想避免这种方式,因为 ExpensiveView 被计算了两次。对于上面的简化版本显然不是问题,但会导致更复杂的问题。

第二种方式,使用带有条件连接子句的单个选择:

with ExpensiveView as (select top 2 ID from Posts order by ID)

select Posts.*
from ExpensiveView
left outer join Posts
ON ExpensiveView.Id = Posts.Id or ExpensiveView.Id = Posts.ParentId

这避免了 ExpensiveView 被评估两次,但会导致大得离谱的聚簇索引扫描。它似乎正在扫描 ExpensiveView 中每个 ID 的整个索引(因此 2 * 14977623 = ~3000 万行)。这非常慢。

两个问题

为什么第二个查询中的条件连接会导致如此大的索引扫描?

有什么方法可以在不对 ExpensiveView 进行多次计算的情况下获得我正在寻找的结果?

最佳答案

试试这个

with
ExpensiveView as (select top 2 ID from Posts order by ID),
CTE_Posts as (
select *, NP.Id as New_Post_ID
from Posts as P
outer apply (select P.Id union all select P.ParentId) as NP
)
select
P.*
from ExpensiveView as E
left outer join CTE_Posts as P on P.New_Post_ID = E.ID

关于sql-server - 使用条件连接语句时执行多个全索引扫描,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17322676/

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