我怎样才能使这个查询 sargable?

Posted

技术标签:

【中文标题】我怎样才能使这个查询 sargable?【英文标题】:How can I make this query sargable? 【发布时间】:2015-09-23 16:46:32 【问题描述】:

我需要从表中检索没有以某个值开头的字段的行:

我目前正在使用这样的简单查询:

SELECT A.ID FROM SCHEMA.TABLE A WHERE A.FIELD NOT LIKE 'WORD%'

但是,我了解到A.FIELD 有时会在“WORD”之前包含不同数量的空格。

显然,我可以使用另一个通配符重新编写查询,但这会使其不可分割并减慢一点(此查询在相当大的表上运行,并且需要尽可能高效)。

有什么办法可以写一个可查询的查询来解决这个问题?

【问题讨论】:

简单的解决方案,清理您的数据并摆脱前导空格。 SQL 不关心尾随空格,但前导空格肯定很重要。 @JorgeCampos 使用 LIKE 并不自动意味着不能使用索引。如果没有前导通配符索引,绝对可以使用。只有在使用前导通配符时,索引才能被使用或提供帮助。 @JorgeCampos 是的,你错了。在这种情况下,它可以使用索引,因为它在开头没有通配符 只要通配符仅在末尾,它仍然可以使用索引。您可能无法获得尖叫的快速搜索,但它至少可以使用它。想想电话簿,即使您只有某人姓氏的前 5 个字符,您也可以进一步缩小结果范围。 如何添加一个计算列来修剪列并在其上添加索引? 【参考方案1】:

如果您因任何原因无法清理数据,一种选择是向表中添加一个计算列,以修剪所有前导和尾随空格:

ALTER TABLE YourTable
    ADD TrimmedYourColumn as (RTRIM(LTRIM(YourColumn)))

并索引计算列:

CREATE INDEX IX_YourTable_TrimmedYourColumn 
    ON YourTable (TrimmedYourColumn)

现在改为搜索该列:

SELECT A.ID FROM YourTable A WHERE TrimmedYourColumn NOT LIKE 'WORD%'

【讨论】:

在 SQL Server 中没有 TRIM 函数,您需要使用 LTRIM(RTRIM(YourColumn)) 代替。 @lad2025 当然,我应该记得那个!【参考方案2】:

ltrim 怎么样?

SELECT A.ID FROM SCHEMA.TABLE A WHERE ltrim(A.FIELD) NOT LIKE 'WORD%'

【讨论】:

嗯,这不符合Is there any way I can write a sargable query to fix this problem? 的要求 我看到您希望确保使用索引。我认为您将不得不清理数据。 SQL仍然很快。无论您是否找到该索引,您的查询都会及时运行。

以上是关于我怎样才能使这个查询 sargable?的主要内容,如果未能解决你的问题,请参考以下文章

关于非规范化。我怎样才能使这个查询更短或更好? (SQL SERVER 2000)[关闭]

为啥这个 pg 查询这么慢?我怎样才能让它更快?

我怎样才能做这个多重 JOIN 查询?

我怎样才能重复这个查询 100 次?

SQLite3-我怎样才能加快这个 SELECT 查询?

我怎样才能用 mongodb 编写这个查询? [复制]