MySQL 使用索引在 OR 上的 ilike 性能优于 %%?

MySQL ilike performance on OR using index is better than %%?

最好使用此 SQL 代码假设在列上应用正确的索引!!

假设常量是来自文本字段的输入!!

select ...
from .....
where lower(column) like 'Constant%' or lower(column) like '%Constant%'

优于?

select ...
from .....
where lower(column) like '%Constant%'

在第一个代码中,我尝试使用 like 来匹配 "constant",但使用索引尝试幸运地找到匹配项,稍后我尝试进行完全匹配!!

只求成绩不下降!我的意思是,如果两个查询同时运行,或者查询有时可以获得性能升级,我觉得没问题

我使用 lower 因为我们使用 DEFAULT CHARSET=utf8 COLLATE=utf8_bin

不,这不会显着提高查询性能。 MySQL 将匹配 WHERE 子句 "per row",因此在继续下一行之前检查所有条件。如果匹配,首先命中索引可能会略微提高性能,但如果第一个条件不匹配,这种增益很可能会被双重评估所取代。

可能有帮助的是:

1) 运行 带有 like 'Constant%'

的查询

2) 运行 另一个查询 like '%Constant%'

在这种情况下,如果有匹配,第一个可能会加速。 但是,您很可能会受到开销的影响,并且在 2 个查询中的性能比在一个查询中的性能更差。

此外,LIKE 运算符不区分大小写。因此,lower(column) 是不必要的。

同时,如果您希望您的数据主要在第一个条件下匹配,而很少在第二个条件下匹配,那么是的,这会导致增加,因为第二个条件未被评估。

我创造了一点table:

create table dotdotdot (
  col varchar(20),
  othercol int,
  key(col)
);

我对与您显示的查询类似的查询进行了解释:

explain select * from dotdotdot where lower(col) = 'value'\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: dotdotdot
   partitions: NULL
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 1
     filtered: 100.00
        Extra: Using where

注意 type: ALL,这意味着它不能使用 col 上的索引。通过使用 lower() 函数,我们破坏了 MySQL 使用索引的能力,它必须求助于 table 扫描,计算每一行的表达式。随着您的 table 变大,这将变得越来越昂贵。

反正也没必要!在默认排序规则中,字符串比较不区分大小写。因此,除非您故意使用区分大小写的排序规则或二进制排序规则来声明 table,否则跳过 lower() 函数调用同样好,因此您可以使用索引。

示例:

explain select * from dotdotdot where col = 'value'\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: dotdotdot
   partitions: NULL
         type: ref
possible_keys: col
          key: col
      key_len: 23
          ref: const
         rows: 1
     filtered: 100.00
        Extra: NULL

type: ref表示使用了非唯一索引。

还比较了使用通配符进行模式匹配。这也打败了索引的使用,它必须进行 table-scan.

explain select * from dotdotdot where col like '%value%'\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: dotdotdot
   partitions: NULL
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 1
     filtered: 100.00
        Extra: Using where

像这样使用通配符进行模式匹配效率非常低!

相反,您需要使用全文索引。

你可能会喜欢我的介绍Full Text Search Throwdown and the video here: https://www.youtube.com/watch?v=-Sa7TvXnQwY


在另一个答案中,您询问使用 OR 是否有帮助。 没有。

explain select * from dotdotdot where col like 'value%' or col like '%value%'\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: dotdotdot
   partitions: NULL
         type: ALL
possible_keys: col
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 1
     filtered: 100.00
        Extra: Using where

请注意,优化器将 col 索引识别为 可能 键,但最终决定不使用它 (key: NULL)。

使用 LOWER() 可防止使用索引。因此,切换到 ..._ci 排序规则并放弃 LOWER.

考虑一个 FULLTEXT 索引;它比 LIKE%...`快 很多。前者快;后者是完整的 table 扫描。

OR 几乎总是性能杀手。