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
几乎总是性能杀手。
最好使用此 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
几乎总是性能杀手。