以下哪种解决方案更好。
Declare @ID as int = 1234
Select MAX(q2.ID)
FROM (SELECT col1,col2 FROM table Where ID=@ID) q1
INNER JOIN table q2 on q1.col1 = q2.col1 and q1.col2=q2.col2
WHERE q2.ID < q1.ID
VS
Declare @col1Val varchar(50)
Declare @col2Val varchar(50)
Select @col1Val=col1, @col2Val=col2 FROM table where ID=@ID
SELECT MAX(ID) FROM table
WHERE ID < @ID AND col1 = @col1Val and col2 = @col2Val
答案 0 :(得分:0)
查询执行计划可能会让您了解哪个执行计划比另一个执行得更好。看来你已经回顾过了,这很棒。
在第二个查询的情况下,我建议尝试在q2表上的ID,col1和col2上创建索引,然后检查执行计划是否特别显示第二个查询的改进。我希望查询的表现同样出色。这个索引是一个涵盖索引,因为你需要的所有
SELECT MAX(ID) FROM table
WHERE ID < @ID AND col1 = @col1Val and col2 = @col2Val
将从索引本身找到。
我怀疑你的第一个查询是使用col1和col2索引(我相信它是一个复合索引)用于where子句的分组和ID(我相信它是主键)。第二个查询可能正在尝试使用能够满足where子句的最佳索引并仅使用主键(如果是聚簇,它将在执行计划中显示为聚簇索引)。
您可以尝试另一种选择。我没有针对虚拟表测试此查询,因此您可能需要稍微调整一下
select top 1 q2.id
from table q2
where exists (
select 1
from table q1
where q1.id=@id
and q1.col1 = q2.col1
and q1.col2 = q2.col2
and q1.id > q2.id
)
order by q2.id desc
OR
select max(q2.id)
from table q2
where exists (
select 1
from table q1
where q1.id=@id
and q1.col1 = q2.col1
and q1.col2 = q2.col2
and q1.id > q2.id
)
如果它们是不同的表,则在id,col1和col2上的q1和q2上添加索引。
您还可以从第一个查询中删除where
子句,然后尝试:
Select MAX(q2.ID)
FROM (SELECT col1,col2 FROM table Where ID=@ID) q1
INNER JOIN table q2 on
q1.col1 = q2.col1
and q1.col2=q2.col2
and q2.ID < q1.ID
试一试。如果您有示例表结构和数据,请随时使用http://sqlfiddle.com创建示例以获得更好的反馈。