gpt4 book ai didi

sql - where中使用OR子句时会使用索引吗

转载 作者:行者123 更新时间:2023-12-02 07:51:59 25 4
gpt4 key购买 nike

我写了一个带有可选参数的存储过程。

 CREATE PROCEDURE dbo.GetActiveEmployee
@startTime DATETIME=NULL,
@endTime DATETIME=NULL
AS
SET NOCOUNT ON

SELECT columns
FROM table
WHERE (@startTime is NULL or table.StartTime >= @startTime) AND
(@endTIme is NULL or table.EndTime <= @endTime)

我想知道是否会使用 StartTime 和 EndTime 上的索引?

最佳答案

是的,它们将被使用(很可能,检查执行计划——但我知道你的参数的可选性不应该有任何区别)

如果您的查询遇到性能问题,则可能是参数嗅探的结果。尝试以下存储过程的变体,看看它是否有任何不同:

CREATE PROCEDURE dbo.GetActiveEmployee
@startTime DATETIME=NULL,
@endTime DATETIME=NULL
AS
SET NOCOUNT ON

DECLARE @startTimeCopy DATETIME
DECLARE @endTimeCopy DATETIME
set @startTimeCopy = @startTime
set @endTimeCopy = @endTime

SELECT columns
FROM table
WHERE (@startTimeCopy is NULL or table.StartTime >= @startTimeCopy) AND
(@endTimeCopy is NULL or table.EndTime <= @endTimeCopy)

这会禁用参数嗅探(SQL 服务器使用传递给 SP 的实际值来优化它)——过去我已经解决了一些奇怪的性能问题——但是我仍然不能令人满意地解释原因。

您可能想尝试的另一件事是根据参数的 NULL 性将查询拆分为几个不同的语句:

IF @startTime is NULL
BEGIN
IF @endTime IS NULL
SELECT columns FROM table
ELSE
SELECT columns FROM table WHERE table.EndTime <= @endTime
END
ELSE
IF @endTime IS NULL
SELECT columns FROM table WHERE table.StartTime >= @startTime
ELSE
SELECT columns FROM table WHERE table.StartTime >= @startTime AND table.EndTime <= @endTime
BEGIN

这很困惑,但如果您遇到问题可能值得一试 - 它有帮助的原因是因为 SQL 服务器的每个 sql 语句只能有一个执行计划,但是您的语句可能会返回截然不同的结果集。

例如,如果您传入 NULL 和 NULL,您将返回整个表和最佳执行计划,但是如果您传入一个小范围的日期,行查找更有可能是最佳执行计划。

将此查询作为单个语句,SQL 服务器被迫在这两个选项之间进行选择,因此查询计划在某些情况下可能不是最优的。通过将查询拆分为多个语句,但是 SQL Server 在每种情况下都可以有不同的执行计划。

(如果愿意,您也可以使用 exec 函数/动态 SQL 来实现相同的目的)

关于sql - where中使用OR子句时会使用索引吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3233996/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com