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

时间:2016-11-09 22:21:58

标签: mysql sql database-performance sql-like

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

假设常量是来自textfield的输入!!

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

优于?

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

在第一个代码中,我尝试匹配“常量”使用喜欢但使用索引尝试幸运找到匹配,然后我尝试进行完全匹配!!

我想要的只是我的表现不降低!我的意思是如果两个查询同时运行,或者查询有时可以获得性能升级,那么我可以使用

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

3 个答案:

答案 0 :(得分:2)

我创建了一个小桌子:

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使用索引的能力,并且它必须求助于表扫描,评估每一行的表达式。随着你的桌子越来越大,这会变得越来越贵。

反正这是不必要的!字符串比较在默认排序规则中不区分大小写。因此,除非您故意使用区分大小写的排序规则或二进制排序规则声明您的表,否则跳过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表示使用非唯一索引。

还可以使用通配符进行模式匹配。这也打败了索引的使用,它必须进行表扫描。

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和视频: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)。

答案 1 :(得分:1)

不,这不会显着提高查询性能。 MySQL将“每行”匹配WHERE子句,因此在继续下一行之前检查所有条件。如果匹配,首先达到指数可能略微提高表现,但如果第一个条件不匹配,这个收益很可能被双重评价所取代。

可能有帮助的是:

1)使用like 'Constant%'

运行查询

2)使用like '%Constant%'

运行另一个查询

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

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

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

答案 2 :(得分:1)

使用LOWER()可防止使用索引。因此,切换到..._ci整理并放弃LOWER

考虑一个FULLTEXT索引;它比<{1}}%...更快很多。前者很快;后者是全表扫描。

LIKE几乎总是性能杀手。