0

我正在尝试在每天接收数百万条记录的表上编写查询。我可以将查询缩小到一个时间片 ( logdate),但我需要其中的其他列数据 ( num)。这是我用来测试它的示例查询:

DECLARE @StartTimeStamp DATETIME = '12/6/2019 7:56:50.799'
DECLARE @EndTimeStamp DATETIME = '12/6/2019 7:56:50.8'

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

SELECT tx.num, tx.logdate 
FROM hsi.transactionxlog tx
WHERE tx.logdate BETWEEN @StartTimeStamp AND @EndTimeStamp

此特定测试的时间跨度为 0.001 秒,运行时间超过四分钟。如果我将其更改为在指定时间范围内未找到任何记录的时间范围,则运行几乎可能需要一秒钟,甚至指定 24 小时的跨度。

该表只有非聚集索引。一个这样的索引num中包含以下列:(按顺序排列)。logdateaction

如何num快速找到@StartTimeStamp 和@EndTimeStamp 之间每条记录的对应关系?我强烈不想在这个表上创建额外的索引,因为许多其他应用程序经常使用它。

4

2 回答 2

0

我找到了一个临时表解决方案。以下是解决方案的精髓:

DECLARE @StartTimeStamp DATETIME = '12/6/2019 7:56:50.799'
DECLARE @EndTimeStamp DATETIME = '12/6/2019 7:56:50.8'
DECLARE @TempTable TABLE (logdate DATETIME, action BIGINT)

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
INSERT INTO @TempTable
    SELECT logdate, action FROM hsi.transactionxlog
    WHERE logdate BETWEEN @StartTimeStamp AND @EndTimeStamp

SELECT tx.num, tx.logdate 
FROM hsi.transactionxlog tx
INNER JOIN @TempTable t ON t.logdate = tx.logdate AND t.action = tx.action
WHERE tx.logdate BETWEEN @StartTimeStamp AND @EndTimeStamp

我真的没有很好的解释为什么会这样,但它更快,并且时间随着 和 之间的时间差@StartTimeStamp而正确缩放@EndTimeStamp。它只是选择几千条记录,然后由于某种原因,SQL 更容易在大表中找到它们。

感谢您查看问题并尝试回答。

于 2019-12-23T17:01:11.990 回答
0

对于此查询:

select tx.num, tx.logdate
from hsi.transactionxlog tx
where tx.logdate BETWEEN @StartTimeStamp AND @EndTimeStamp;

最优指数为: transactionxlog(logdate, num)。应该是索引中的logdate第一个键,因此它用于where条件。

于 2019-12-13T00:23:30.353 回答