【问题标题】:What is the performance impact with using IS NULL OR vs. ISNULL with LIKE?将 IS NULL OR 与 ISNULL 与 LIKE 一起使用对性能有何影响?
【发布时间】:2018-08-08 17:49:59
【问题描述】:

我正在编写一个参数化查询,其中要求LIKE 子句在field LIKE '%' 时包含NULL 值。

我有多种解决方案;我并排运行这些查询,它们返回具有相同摘要的相似执行计划,并且查询时间相似。我担心这些查询如何提高具有数百万条记录的表的性能。

-- Where @PartId is typically '%' or could be 'Part123%'.
SELECT *
FROM dbo.OrderItems AS oi
WHERE oi.PartId IS NULL OR oi.PartId LIKE @PartId

SELECT *
FROM dbo.OrderItems AS oi
WHERE ISNULL(oi.PartId, '') LIKE @PartId

SELECT *
FROM dbo.OrderItems AS oi
WHERE COALESCE(oi.PartId, '') LIKE @PartId

这个question 表明ISNULLCOALESCE 之间几乎没有区别。 Grant Fritchey 在这个article 中演示了在WHERE 子句上应用函数会导致比使用LIKE 更大的性能障碍,但是我读到使用逻辑OR 会导致查询中的性能问题。使用 IS NULL OR 与替代 ISNULL 相比,性能影响是什么?

编辑:这是查询的执行计划摘要:

【问题讨论】:

  • 我认为第一个查询不能按预期工作,因为它返回带有空值的行而不查看 @CustomerName
  • 这些不是执行计划,它们只是计划的摘要。右键单击并点击 Show XML 以查看实际计划。通过比较 XML,您会发现它们实际上是否在做同样的事情,或者它们是否恰好具有相同的摘要。
  • 搜索逻辑会影响性能。这是一个愚蠢的扫描,没有机会发生其他任何事情。由于特定的数据模型和搜索逻辑。在给定条件下使用“ISNULL”不会比更改 T-short 效果更好。
  • 像这样的 Catch-All 查询最好用动态 sql 处理。 sqlinthewild.co.za/index.php/2009/03/19/catch-all-queries
  • 您还可以通过添加 SET STATISTICS TIME, IO ON; 获得一些额外的见解;然后将几个不同的参数选项传递给所有三个查询。

标签: sql sql-server tsql


【解决方案1】:

您没有粘贴选择的计划,但我只能假设它涉及表扫描?

有时值得重写 SQL 以使用联合查询,而不是使用“WHERE CONDITION1 OR CONDITION2”:

SELECT *
FROM dbo.Customers AS c
WHERE c.Name IS NULL 
UNION ALL
SELECT *
FROM dbo.Customers AS c
WHERE c.Name = @CustomerName

可以防止表扫描。

【讨论】:

  • 我已将执行计划添加到问题中 - 这是一个表扫描。
  • 我刚刚编辑了我的答案以删除不必要的 LIKE 关键字(替换为“=”)
  • 当参数不是'%' 时,这包括NULL 记录。如果值是'Bob%'怎么办?
【解决方案2】:

不太确定您的查询逻辑。你的 where 子句

oi.PartId IS NULL OR oi.PartId LIKE '%'

另外两个 where 子句只是 literally 的意思是“选择我记录 PartID 为 null PartID NOT null”的记录。

既然 PartID 只能为 NULL 或不能为 null,那为什么首先需要 where 子句呢?

【讨论】:

  • 因为'%' 将被参数化。其他值可以提供给查询,例如'AB123%' 并且不包括 NULLs。
【解决方案3】:

你测试了吗?仅测试like '%' 是有缺陷的结果。如果您将like 替换为=,它仍然存在缺陷。

这些查询返回不同的结果!

declare @match varchar(10)  = '%match%';
declare @val varchar(10) = null;

select 'yes' 
where @val is null or @val like @match;

select 'yes'
where isnull(@val, '') like @match;

【讨论】:

    猜你喜欢
    • 2017-12-04
    • 1970-01-01
    • 2010-09-13
    • 2021-10-22
    • 2018-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-13
    相关资源
    最近更新 更多