SQL Server 2005中的SQL查询优化(CTE+范围函数)

发布于 2024-07-29 19:47:19 字数 522 浏览 5 评论 0原文

我想知道这样的查询是否可以优化。 我已经极大地简化了它,你可以看到它的核心。

with Rec (Id,Name,ParentId)
as
(
    select Id,Name,ParentId from Departments where ParentId is null
    union all
    select d.Id, d.Name, d.ParentId from Departments d join Rec r on 
    (d.ParentId=r.Id)
)
select q.* from (
select ROW_NUMBER() OVER (ORDER BY r.Id DESC) AS [ROW_NUMBER], r.* from Rec r
) as q
where q.[ROW_NUMBER] between 100 and 200

它的作用是分层查询下属部门,然后对其进行范围分析。

我最终得到了一个巨大的执行计划,并想知道是否可以以不同的方式完成它。

谢谢。

I'm wondering whether such query could be potentially optimized.
I've hugely simplified it, and you see the core of it.

with Rec (Id,Name,ParentId)
as
(
    select Id,Name,ParentId from Departments where ParentId is null
    union all
    select d.Id, d.Name, d.ParentId from Departments d join Rec r on 
    (d.ParentId=r.Id)
)
select q.* from (
select ROW_NUMBER() OVER (ORDER BY r.Id DESC) AS [ROW_NUMBER], r.* from Rec r
) as q
where q.[ROW_NUMBER] between 100 and 200

What it does is hierarchically query the desendent departments and then do a ranging upon it.

I'm ending up with a huge execution plan and wondering if it can be done in a different manner.

Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

愁杀 2024-08-05 19:47:19

我想考虑到以下假设,情况可能会更好一些:

  1. 您通过 ParentId 有正确的索引
  2. 您从表中检索大量数据(大多数列)

可以做什么:为了减少 io 子系统的负载,我们可以首先组成一个 Id 列表,对它们进行分页(即按 RowNumber 进行过滤),然后才包含所有其他列。 这将有效地导致使用 ParentId 索引,考虑到上述两个假设,这应该会快得多。

所以这是我“亲自”提出的建议:

with Rec (Id,ParentId)
as
(
    select Id,ParentId from Departments where ParentId is null
    union all
    select d.Id, d.ParentId from Departments d join Rec r on 
    (d.ParentId=r.Id)
),
Paged 
as
(
    select * from (
        select ROW_NUMBER() OVER (ORDER BY r.Id DESC) AS [ROW_NUMBER], r.* from Rec r
    ) as q
    where q.[ROW_NUMBER] between 100 and 200
)
select * 
from 
    Paged
    inner join Departments d on d.Id = Paged.Id

I quess it could be a bit better given the following assumptions:

  1. You have proper index by ParentId
  2. You retrieve a lot of data (most of the columns) from the table

What can be done: in order to reduce load on io subsystem we can first compose a list of Id's, page them (i.e. filter by RowNumber) and only after that include all other columns. This will effectively result in working with index by ParentId which should be a lot faster given the above two assumptions.

So here's my proposition 'in person' so to say:

with Rec (Id,ParentId)
as
(
    select Id,ParentId from Departments where ParentId is null
    union all
    select d.Id, d.ParentId from Departments d join Rec r on 
    (d.ParentId=r.Id)
),
Paged 
as
(
    select * from (
        select ROW_NUMBER() OVER (ORDER BY r.Id DESC) AS [ROW_NUMBER], r.* from Rec r
    ) as q
    where q.[ROW_NUMBER] between 100 and 200
)
select * 
from 
    Paged
    inner join Departments d on d.Id = Paged.Id
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文