我需要根据日期范围从包含500万条记录的表中选择记录。返回结果需要19秒。只有ID字段是主键,日期字段未编入索引。
所选记录计数仅为500.可以采取哪些措施来优化查询?
select *
from productdetail
where createddate >= '01 Jan 2016'
and createddate <= '05 mar 2016'
任何建议/帮助表示感谢。
答案 0 :(得分:0)
通常,没有更好的方法,搜索非索引列必须执行线性搜索。
但在您的情况下,如果主键是自动增量并且createddate
表示记录创建日期(这意味着更大的主键,更晚的createddate
日期/时间记录),您可以手动执行二进制搜索主键。
下面是一个示例,ID
是从0开始的自动增量主键(索引)。每个选择语句仅涉及ID
,因此查询速度很快。
请注意,仅当createddate
相对于主键ID
排序时,此功能才有效:
DECLARE @lowerBoundID INT
DECLARE @upperBoundID INT
DECLARE @maxID INT
SELECT @maxID = MAX(ID) FROM productdetail
SET @lowerBoundID = 0
SET @upperBoundID = @maxID
IF (SELECT createddate FROM productdetail WHERE ID = @lowerBoundID) > '05 mar 2016' OR (SELECT createddate FROM productdetail WHERE ID = @upperBoundID) < '01 Jan 2016'
BEGIN
DECLARE @first INT
DECLARE @last INT
DECLARE @middle INT
SET @first = 0
SET @last = @maxID
SET @middle = (@first + @last) / 2
WHILE @last - @first > 1
BEGIN
IF (SELECT createddate FROM productdetail WHERE ID = @middle) < '01 Jan 2016'
SET @first = @middle
ELSE
SET @last = @middle
SET @middle = (@first + @last) / 2
END
IF (SELECT createddate FROM productdetail WHERE ID = @first) < '01 Jan 2016'
SET @lowerBoundID = @last
ELSE
SET @lowerBoundID = @first
SET @first = 0
SET @last = @maxID
SET @middle = (@first + @last) / 2
WHILE @last - @first > 1
BEGIN
IF (SELECT createddate FROM productdetail WHERE ID = @middle) > '05 mar 2016'
SET @last = @middle
ELSE
SET @first = @middle
SET @middle = (@first + @last) / 2
END
IF (SELECT createddate FROM productdetail WHERE ID = @last) > '05 mar 2016'
SET @upperBoundID = @first
ELSE
SET @upperBoundID = @last
SELECT * FROM productdetail WHERE ID >= @lowerBoundID AND ID <= @upperBoundID
END
答案 1 :(得分:-3)
将 createddate 设为非聚集索引,并将搜索查询放入存储过程。存储过程将花费更少的时间来检索数据。
希望这有帮助 感谢..