【问题标题】:Performance of LIKE 'xyz%' v/s LIKE '%xyz'LIKE 'xyz%' v/s LIKE '%xyz' 的性能
【发布时间】:2023-03-20 08:58:01
【问题描述】:

我想知道LIKE 运算符实际上是如何工作的。 它是否只是从字符串的第一个字符开始并尝试匹配模式,一个字符向右移动?或者它是否查看% 的位置,即如果它发现% 是模式的第一个字符,它是否从最右边的字符开始并开始匹配,每个字符向左移动一个字符匹配成功?

我现在没有任何用例,只是好奇。

编辑:缩小问题范围

【问题讨论】:

标签: mysql sql oracle tsql sql-like


【解决方案1】:

如果列上有索引,将常量字符放在前面将导致您的 dbms 使用更有效的搜索/搜索算法。但即使是最简单的形式,dbms 也必须测试字符。如果它能够在早期发现它不匹配,它可以丢弃它并进入下一个测试。

【讨论】:

  • +1 。 . .这是唯一提到索引的答案。 Like 可以在通配符不在字符串开头时使用索引——这是一个非常重要的性能考虑因素。
【解决方案2】:

LIKE 搜索条件使用通配符在字符串中搜索模式。例如:

WHERE name LIKE 'Mickey%'

将定位所有以 'Mickey' 开头的值,可选地后跟任意数量的字符。 % 不区分大小写也不区分重音,您可以使用多个 %,例如

WHERE name LIKE '%mouse%'

将返回所有包含“鼠标”(或“鼠标”或“鼠标”)的值。

% 包含在内,表示

WHERE name like '%A%'

将返回以“A”开头、包含“A”或以“A”结尾的所有内容。

您可以使用 _(下划线)表示单个位置上的任何字符:

WHERE name LIKE '_at%'

将为您提供所有以“a”为第二个字母和“t”为第三个字母的值。第一个字母可以是任何东西。例如:“蝙蝠侠”

在 T-SQL 中,如果使用 [],则可以查找范围内的值。

WHERE name LIKE '[c-f]%'

它将查找以 c 和 f 之间的字母开头的任何值,包括两者。这意味着它将返回以 c、d、e 或 f 开头的任何值。此 [] 仅适用于 T-SQL。使用 [^ ] 查找不在范围内的值。

查找所有包含数字的值:

WHERE name LIKE '%[0-9]%'

返回包含数字的所有内容。示例:“教父2”

如果您要查找所有第 3 位为“-”(破折号)的值,请使用两个下划线:

WHERE NAME '__-%'

它将返回例如:'Lo-Res'

查找名称以 'xyz' 结尾的值:

WHERE name LIKE '%xyz'

返回任何以 'xyz' 结尾的东西

使用方括号在名称中查找 % 符号:

WHERE name LIKE '%[%]%'

将返回例如:'Top%Movies'

搜索 [ 使用括号括起来:

WHERE name LIKE '%[[]%'

给出的结果为:'New York [NY]'

数据库排序规则的排序顺序确定区分大小写和字符范围的排序顺序。您可以选择使用 COLLATE 来指定 LIKE 运算符使用的排序规则。

【讨论】:

  • 感谢 @J3ffk,我知道 like 运算符,我正在寻找 db 在评估这些条件时所做的性能和优化
  • 抱歉没有具体回答您的问题;至于您问题的性能部分,我建议对示例数据库进行测试并使用上述选项测量性能。
【解决方案3】:

通常主要的性能瓶颈是 IO。 LIKE 运算符的效率只有在您的整个表适合内存时才重要,否则 IO 将占用大部分时间。

AFAIK oracle 可以使用索引进行前缀匹配。 (如 'abc%'),但这些索引不能用于更复杂的表达式。 无论如何,如果您只有这种查询,您应该考虑在相关列上使用简单索引。 (可能其他 RDBMS 也是如此。)

否则 LIKE 操作符通常很慢,但大多数 RDBMS 都有某种全文搜索解决方案。我认为慢的主要原因是LIKE太笼统了。通常全文索引有很多不同的选项,可以告诉数据库您真正想要搜索的内容,并且通过这些附加信息,数据库可以更有效地完成其任务。

根据经验,我认为如果您想在文本字段中搜索并且您认为性能可能是一个问题,您应该考虑您的 RDBMS 的全文搜索解决方案,或者真正的目标不是文本搜索,但这是某种“设计副作用”,例如 xml/json/statuses 作为文本存储在字段中,那么您可能应该考虑选择更有效的数据存储选项。 (如果有的话……)

【讨论】:

  • 谢谢@Lajos,我已经缩小了我的问题,我想了解startsWith和endsWith条件之间的区别
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-06-11
  • 2011-09-02
  • 2015-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-27
相关资源
最近更新 更多