【问题标题】:How to change "LIKE '1%'" so that it is efficient for integers?如何更改“LIKE '1%'”以使其对整数有效?
【发布时间】:2014-09-08 18:43:58
【问题描述】:

我想要这样的查询:

SELECT TOP 60 lcode
FROM LessonChart
WHERE lcode LIKE '1%'

但是 SQL Server 说 int 到 varchar 的转换不好,关键字“LIKE”效率不高...

我应该做什么来代替这段代码?

【问题讨论】:

  • 更改设计,使操作不需要。也许它不应该是一个 INT 列?
  • 这是因为 LIKE 用于评估字符值,而不是整数。您必须将您的 lcode 转换为 varchar 才能正常工作。
  • @SeanLange SQL Server will automatically perform a cast 这里(不确定其他供应商),但一个大问题是查询不再是Sargable。 OP 清楚地说明了问题“将 int 转换为 varchar 不好”并且关键字“LIKE”效率不高”。
  • 它不是 sargable 的原因是因为隐式转换。这都是错误数据类型的尖叫声。
  • 你想从数据中得到什么?所有以1开头的东西? 1、10、100、1234 等

标签: sql-server type-conversion int sql-like varchar


【解决方案1】:

核心问题 - 以及警告 - 即使 lcode LIKE '1%' 在 SQL Server (it accepts the syntax and perform an implicit cast) 中工作,但在这样做时,查询不再是 Sargable。这意味着由于隐式转换,INT 列上的任何索引都不能用于 LIKE 操作。

.. 如果 DBMS 引擎可以利用索引来加速查询的执行,则称该查询是可跟踪的。该术语源自 Search ARGument ABLE 的缩写。

无法使用索引的这种损失并非特定于 CAST-and-then-LIKE 操作,它也会影响conditions that use the column in other expressions, such as math。虽然警告很好,但 SQL Server 相当有限,它会直接抱怨哪些查询 - 慢查询可能只是慢查询。

如果这种索引丢失的使用不是(也不会是)问题,因为只有相对较少的行应用了条件(例如,数据很少或查询已经将候选者减少到合理的数字),那么不要担心 - 但请继续阅读,因为无论如何都可能需要进行更改。请参阅Display and Save Execution Plans,连同实际数据库设计/增长的知识,可以帮助您做出决定。

如果不能使用索引是一个问题或将是一个问题(因为谓词应用到数万行甚至数百万行),或者如果寻找可能的方法来简单地清理查询,那么:

  1. 评估设计。它真的是一个 integer 值(例如金额)还是仅使用数字(例如电话号码或邮政编码)的 标识符? p>

    如果是后者考虑将设计更改为 CHAR/VARCHAR 并添加索引。这将修复可搜索性问题使列/类型更好地表示信息。

  2. 再次评估设计。这个前导的“1”是否表示与标识符的其余部分分开的信息?如果是这样,是否可以/应该将其规范化为单独的列?

    如果将其分开有意义,则创建一个单独的可索引(位?)列并继续。

    即使它不应该被“分开”,也可以使用persisted computed column。 (虽然标识符/lcode 现在将包含冗余信息,但不会直接对其进行查询。)

    计算列是根据可以使用同一表中的其他列的表达式计算得出的。通过将计算列标记为 PERSISTED,您可以在计算列上创建确定性索引。..

  3. 如果设计是正确的,以上都不适用,并且出于性能原因查询必须能够使用索引,那么编写查询以便它可以使用索引。这是一个 能够使用索引的组合(并注意它有多少组合,见上文)。

    WHERE lcode = 1
       OR lcode BETWEEN 10 AND 19
       OR lcode BETWEEN 100 AND 199
      -- etc
    

    对于少量的行,这无关紧要,但是随着谓词中涉及的行数的增加,使用(甚至是丑陋的)可索引查询可以避免因必须加载/扫描过多的行。

【讨论】:

    猜你喜欢
    • 2019-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-12
    • 2021-11-18
    • 2011-10-14
    相关资源
    最近更新 更多