【问题标题】:Best method to make search for any number of <space>s sargable搜索任意数量的 <space> sargable 的最佳方法
【发布时间】:2018-04-24 09:20:20
【问题描述】:

我们正在寻求改进一个 SQL WHERE 子句,该子句过滤 NULL 和仅包含空白的值,但发现很难让解决方案使用该列上的索引,从而使 sargable。

原文:

where isnull(ltrim(rtrim(ean_code)), N'') <> N''

建议:

where EAN_CODE is not null and EAN_CODE NOT IN ('', ' ', '  ', '   ', '    ', '     ')

有没有更好的解决方案?

【问题讨论】:

  • 如果一个值只包含空格,那么 LEN(value) = 0value = '',这要归功于 SQL 的一个怪癖,其中尾随空格不计算在内。您也许可以利用它来发挥自己的优势。 (如,一个简单的EAN_CODE &lt;&gt; '' 应该足以满足所有情况。)
  • @JeroenMostert 不幸的是,基于列的函数不会使用索引 - 不可分割。
  • @cloudsafe 但是EAN_CODE &lt;&gt; '' 会使用你的索引。
  • 所以不要使用函数?就像我说的那样,您提出的解决方案包含在 WHERE EAN_CODE &lt;&gt; '' 中,它 1) 通过与实际值进行比较来排除 NULL 和 2) 通过尾随空白规则和 3) 允许使用指数。请注意,如果您的大多数值不是空白(如您所料),SQL Server 可能仍然有效地只是扫描索引而不是查找它,因为查询不是选择性的,但这是另一个问题。如果这是你的问题,那么无论如何你都需要一个不同的策略。
  • @JeroenMostert 你是绝对正确的。这将节省大量时间、精力和性能。

标签: sql-server indexing sql-server-2012


【解决方案1】:

正如 Jeroen Mostert 在 cmets 中所写,您需要做的就是检查列是否不等于空字符串。

创建并填充示例表(在您以后的问题中保存我们这一步)

DECLARE @T AS TABLE
(
    Id int identity(1,1),
    Col varchar(10)
)

INSERT INTO @T (Col) VALUES
(''), 
(' '), 
('  '), 
('   '),
('    '),
('z'), 
(NULL)

查询:

SELECT *
FROM @T
WHERE Col != ''

结果:

Id  Col
6   z

You can see a live demo on rextester.

【讨论】:

  • 请注意,如果Col != '',则根据定义,Col IS NOT NULL(幸运的是,与ANSI_NULLS无关)。为了清楚起见,您可能仍然觉得需要明确地写出来,但这对查询没有任何影响。
  • @JeroenMostert 好点。我没想到。编辑。
【解决方案2】:

这应该足够了

declare @t table
(
    Val VARCHAR(20)
)

INSERT INTO @t
VALUES(null),(''),(' '),('   '),('Sample'),(' Sample1'),('Sample2 '),(' Sample3 ')

select
    *
    from @t
       WHERE LTRIM(RTRIM(ISNULL(Val,'')))<>''

或者你也可以试试这个

select
    *
    from @t
       WHERE LEN(LTRIM(RTRIM(REPLACE(ISNULL(Val,''),' ',''))))<>0

输出

【讨论】:

  • @Jayasuraya Satheesh 这不是 sargable 所以不会使用索引。
猜你喜欢
  • 2015-04-19
  • 2012-05-18
  • 1970-01-01
  • 2013-10-09
  • 1970-01-01
  • 1970-01-01
  • 2010-11-13
  • 1970-01-01
  • 2013-08-17
相关资源
最近更新 更多