用于比较表中日期字段的 SQL Server 索引策略

问题描述 投票:0回答:1

我有一个带有重复查询的 SQL Server 表,我需要提高其性能。我需要检索与下面的 where 子句匹配的记录。所有 3 列都是 datetime2 列。

WHERE GREATEST(dateColumn1, dateColumn2) > dateColumn3

为表建立索引以提高性能的最佳方法是什么?

我应该创建一个计算列并为其建立索引吗?

sql sql-server indexing
1个回答
0
投票

为表建立索引以提高性能的最佳方法是什么?

将您的

WHERE
谓词子句表达式放入计算列中,然后对该列建立索引。


上次我检查时,SQL Server(包括 Azure SQL)不支持在

CREATE INDEX
语句中使用任意表达式,因此您想要索引的任何表达式都必须定义为计算(但不一定是
PERSISTED
)列
.

...几个月前我自己就这样做了,但我遇到了一个😩诱发错误:如果你在SQL Server 2022 或 Azure SQL 中的计算列表达式。 因为您需要定义一个将按原样索引的计算列,然后考虑您可以...


将计算列简单地定义为 
PERSISTED
 的结果 - 这意味着您仍然需要在 
LEAST

查询中进行

GREATEST 比较,并且如果您的查询发生哪怕最轻微的变化,也可能会遇到糟糕的查询计划选择。数据库。

使用
    GREATEST( col1, col2, etc )
  1. 表达式的结果定义
    另一个 
    计算列,并在其上定义
    >
    ;您需要更新您的
    SELECT
    查询以直接引用新的计算列,但这会显着降低 SQL Server 生成错误查询计划的几率(但 YMMV、ofc)。
  2. (我假设你的>
    INDEX
    列都是
    SELECT
    。(如果它们实际上是
    dateCol1
  3. ,那么这个答案可能对你不起作用,因为这里的计算列和索引不会处理
dateCol2

datetime2(7) NOT NULL
 式谓词)
无论如何,像这样:
NULL
请注意,我定义了 dateCol1 IS NOT NULL
dateCol1 IS NOT DISTINCT FROM dateCol2
- 以及关联的

-- Before doing anything, ensure we're in a standards-compliant environment, which is important for PERSISTED columns: SET ANSI_NULLS, ANSI_PADDING, ANSI_WARNINGS, ARITHABORT, CONCAT_NULL_YIELDS_NULL, QUOTED_IDENTIFIER ON SET XACT_ABORT ON; BEGIN TRANSACTION ddlTxn; RAISERROR( 'Now running ALTER TABLE...', 0, 1) WITH NOWAIT; ALTER TABLE dbo.MyTable ADD Greatest_1_or_2 AS GREATEST( dateCol1, dateCol2 ) PERSISTED NOT NULL, DateCol_1_or_2_is_gt_3 AS ( CASE WHEN GREATEST( dateCol1, dateCol2 ) > dateCol3 THEN CONVERT(bit,1) ELSE CONVERT(bit,0) END ) PERSISTED NOT NULL, DateCol_1_or_2_diff_3 AS ( DATEDIFF( microsecond, GREATEST( dateCol1, dateCol2 ) - dateCol3 ) PERSISTED NOT NULL; RAISERROR( 'Now running CREATE INDEX...', 0, 1) WITH NOWAIT; CREATE INDEX IX_Greatest12 ON dbo.MyTable ( Greatest_1_or_2 ) INCLUDE ( dateCol3 ); CREATE INDEX IX_Greatest12IsGT3 ON dbo.MyTable ( DateCol_1_or_2_is_gt_3 ); CREATE INDEX IX_DateCol12Diff3 ON dbo.MyTable ( DateCol_1_or_2_diff_3 ); COMMIT TRANSACTION ddlTxn;

索引 - 因此您可能希望根据实际查询选择一组或另一组(或两者?)。

因此您的查询现在可能如下所示:

DateCol_1_or_2_is_gt_3

或:
DateCol_1_or_2_diff_3
或:

IX_

您需要自己测试和基准测试这 3 种不同的变体,因为总体上哪个更快或更优完全取决于数据库的其余部分如何工作,从我的角度来看,

在互联网上

,我什么也看不见:)
    

© www.soinside.com 2019 - 2024. All rights reserved.