【问题标题】:SQL query optimization: get extra column data from non-clustered indexSQL查询优化:从非聚集索引中获取额外的列数据
【发布时间】:2020-04-06 09:38:09
【问题描述】:

我正在尝试在每天接收数百万条记录的表上编写查询。我可以将查询缩小到一个时间片 (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 小时的跨度。

这个表只有非聚集索引。一个这样的索引包含以下列:(numlogdateaction,按此顺序)。

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

【问题讨论】:

  • 这是一个非常直接的查询,如果您在索引中添加 lodate 可以加快速度。您是按毫秒还是按日期查询?我问的原因是您是否可以考虑使用 = Date_field 而不是 between 。你也检查过解释计划和调优顾问是怎么说的吗?
  • 该表上有两个具有 logdate 的索引,一个是 logdateactionusernum,另一个是上面发布的。我确实打算通常一次查询大约五分钟,很抱歉,但我不能使用 =。我将它隔离到可能的最小时间范围,以尝试找出我可以使用的最大时间范围。我对解释计划或调优顾问一无所知,但如果我对数据库有权限,我会调查这些。

标签: sql query-optimization non-clustered-index


【解决方案1】:

对于这个查询:

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

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

【讨论】:

  • 如果可以避免的话,我不想在这个表中添加索引,因为它是其他应用程序不可或缺的一部分。放弃我自己的应用程序甚至可能是一个更好的选择。
【解决方案2】:

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

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 更容易在大表中找到它们。

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

【讨论】:

    猜你喜欢
    • 2023-03-17
    • 2012-08-05
    • 1970-01-01
    • 2023-02-03
    • 1970-01-01
    • 2018-05-08
    • 1970-01-01
    • 2014-08-27
    • 2018-03-07
    相关资源
    最近更新 更多