Jua*_*lez 6 performance sql-server-2008 sql-server subquery query-performance
如果我运行以下代码:
select PolicyNumber, MAX(decpageid) as decpageid, Risk
from StatRiskDecpages
where PolicyNumber = 'AR-0000301132-04'
group by PolicyNumber, Risk
Run Code Online (Sandbox Code Playgroud)
我得到以下结果:
PolicyNumber decpageid Risk
AR-0000301132-04 41 1
AR-0000301132-04 41 2
AR-0000301132-04 37 3
Run Code Online (Sandbox Code Playgroud)
我真正想要检索的是policynumber和最大decpageid(在这种情况下为41)以及风险数字(应该是1和2)
该查询还返回 decpageid 37,即使它不是 policynumber 的最大 decpageid,因为它具有不同的风险。
我想返回的结果是:
PolicyNumber DecpageID Risk
AR-0000301132-04 41 1
AR-0000301132-04 41 2
Run Code Online (Sandbox Code Playgroud)
我已经想出了 2 个不同的查询,我可以用它来返回我想要的结果,但我认为它们不是最有效的。我提出的问题是:
select PolicyNumber, MAX(decpageid) as decpageid, Risk
from StatRiskDecpages
where
PolicyNumber = 'AR-0000301132-04'
and decpageid = (
select MAX(decpageid)
from StatRiskDecpages
where PolicyNumber = 'AR-0000301132-04'
)
;
Run Code Online (Sandbox Code Playgroud)
这将返回所需的结果,但我不想在查询中多次指定策略编号。有没有办法从外部查询将 policynumber 调用到子查询中?
我想出的另一个查询是:
select t1.PolicyNumber,t2.DecpageID, t2.Risk
from (
select PolicyNumber, MAX(decpageid) as decpageid
from StatRiskDecpages
where PolicyNumber = 'AR-0000301132-04'
group by PolicyNumber
) as t1
left join StatRiskDecpages as t2
on t1.PolicyNumber = t2.PolicyNumber
and t1.decpageid = t2.DecpageID
;
Run Code Online (Sandbox Code Playgroud)
我喜欢这个查询,因为我只需要指定 policynumber 1 次,我还可以扩展查询,以便我可以返回多个 policynumber 的信息。
我需要知道的是,这是否是编写查询的最有效方式?似乎有点多余。我可能是错的,但我认为可能有更好更有效的方式来编写查询。有什么建议?
我可能会用
SELECT TOP (1) WITH TIES PolicyNumber,
decpageid,
Risk
FROM StatRiskDecpages
WHERE PolicyNumber = 'AR-0000301132-04'
ORDER BY decpageid DESC
Run Code Online (Sandbox Code Playgroud)
假设这个覆盖索引(PolicyNumber, decpageid) INCLUDE(Risk)会给你一个计划

这是我重构您的查询的方式。(首先我将您的查询与您的执行计划一起发布,然后是我的新查询和相应的查询计划)
您的查询
Select
t1.PolicyNumber,
t2.DecpageID,
t2.Risk
from
(
select
PolicyNumber,
MAX(decpageid) as decpageid
from StatRiskDecpages
where PolicyNumber = 'AR-0000301132-04'
group by PolicyNumber
) as t1
left join StatRiskDecpages as t2
on t1.PolicyNumber = t2.PolicyNumber
and t1.decpageid = t2.DecpageID
Run Code Online (Sandbox Code Playgroud)
您的查询的执行计划如下:

然后我写了这样的查询,给出了相同的期望结果:
我的查询
select
p.PolicyNumber,
p.decpageid,
p.Risk
from StatRiskDecpages p
where decpageid in
(
select max(decpageid)
from StatRiskDecpages
where PolicyNumber = p.PolicyNumber
)
Run Code Online (Sandbox Code Playgroud)
这显示了一个执行计划:

请注意单个表扫描(与您的两个表扫描相反),以及缺少用于 JOIN 的嵌套循环。
至于什么看起来更好,更易于维护,我认为它们都是相对可行的。只是替代方案的一些想法和图形表示。