以下是该场景:有一个软件表(PK = SoftwareID)和一个关联的Release表(PK = [SoftwareID,Version])。
版本可以是主要版本或次要版本,版本类型由Release.ReleaseType('MAJ','MIN')标识。
版本的特征还有日期:Release.ReleaseDate。
软件按类别划分,由Software.CategoryID标识。
问题:需要一个有效 T-SQL查询来列出某个类别的所有软件,并且第一个主要发布日期在给定的时间间隔内,由@DateFrom,@ DateTo分隔。最终结果集中唯一需要的列是SoftwareID和ReleaseDate。
这不是真实情况,但我这样制定它更容易理解。在实际案例中,表格Release将有大约1000万条记录,表格软件大约有100万条。我已经找到了一个解决方案,但它很慢,我觉得这里的专家可能会找到更好的东西。
这是我的慢解决方案:
select s.SoftwareID, min(r.ReleaseDate)
from
Software s inner join Release r on (s.SoftwareID = r.SoftwareID)
where s.CategoryID = @Category
and r.ReleaseType = 'MAJ'
group by
s.SoftwareID
having
min(r.ReleaseDate) >= @DateFrom
and min(r.ReleaseDate) < @DateTo
感谢。
答案 0 :(得分:2)
您的查询很好。
您可能希望确保查询具有正确的索引:
答案 1 :(得分:1)
您可能遇到索引问题。您是否尝试在ReleaseDate列上创建索引或在包含ReleaseDate的表上创建聚簇索引(按ReleaseDate排序)?
答案 2 :(得分:1)
尝试以下方面的内容:
select
s.SoftwareID,
min(r.ReleaseDate)
from
Software s
inner join Release r on s.SoftwareID = r.SoftwareID
where
s.CategoryID = @Category
and r.ReleaseType = 'MAJ'
and s.ReleaseDate >= @DateFrom
and s.ReleaseDate < @DateTo
group by
s.SoftwareID
基本思路是:为什么在分组后过滤日期,以防止不需要的记录在分组之前输入结果。
您正在s.SoftwareID
进行分组。对我而言,似乎HAVING MIN(s.ReleaseDate) >= ...
无法影响与WHERE s.ReleaseDate >= ...
不同的记录。
答案 3 :(得分:1)
谢谢大家的建议。问题似乎几乎已经解决,我认为没有太多工作要做。
查询顾问建议了两个有用的索引,其中一个类似于:
CREATE NONCLUSTERED INDEX [IX_Release_1234] ON [dbo].[Release]
(
[ReleaseType] ASC,
[SoftwareID] ASC
)
INCLUDE ( [ReleaseDate]) WITH (SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF) ON [PRIMARY]
索引调整将执行时间减少到不到50%。但是,另一个轻微的改进(之前减半时间的25-30%)是重新组织查询,首先从Release表中获取发布日期,然后将此子查询与Software连接:
select s.SoftwareID, r.ReleaseDate
from Software s inner join (
select SoftwareID, min(ReleaseDate) as ReleaseDate
from Release
where ReleaseType = 'MAJ'
group by SoftwareID
having
min(ReleaseDate) >= @DateFrom
and min(ReleaseDate) < @DateTo
) r on (
s.SoftwareID = r.SoftwareID
)
where
s.CategoryID = @Category
现在我猜索引调整应该重做:)...
最重要的是,尽可能使用引擎调整顾问,再次感谢大家。