【问题标题】:impact of database Index on regular expression queries in MySQLMySQL中数据库索引对正则表达式查询的影响
【发布时间】:2013-11-11 00:11:57
【问题描述】:
数据库索引旨在加快查找速度,但是在索引列的 where 子句中使用正则表达式的查询的性能如何。
假设我们有一个表FILES,其中有一个字段FILE_NAME,我们在FILE_NAME 上创建了一个索引。
然后我们有一个查询来搜索具有匹配名称模式的文件
SELECT * FROM FILES WHERE FILE_NAME RLIKE regexp
在 FILE_NAME 上创建索引是否有助于提高上述查询的性能??
【问题讨论】:
标签:
mysql
sql
regex
database
indexing
【解决方案1】:
是的,它可能会提高性能 - 但不是您想的那样。
在正常使用中,索引允许 DBMS 查找表中的行而无需扫描每个条目 - 它可以跳过一些(用于范围比较、特定值和部分匹配,例如 LIKE 'ABC%' 但不能 em> 用于查询 LIKE '%XYZ')。当您尝试使用数据的某种转换来查找行时(尽管有语法,RLIKE 是一个基于操作数而不是运算符的函数),DBMS 必须将转换应用于表的每一行。一些 DBMS(例如 Oracle)支持基于函数的索引,因此只要您的正则表达式是常量,您就可以根据正则表达式匹配定义一个索引 - MariaDB 支持可以被索引的虚拟列,这相当于同一件事。
因此,在此处使用索引不会减少 DBMS 为过滤查询而必须获取的行数。
但是,如果匹配数相对于基础数据中的行数较低,并且索引的宽度相对于表行的宽度较小,则 DBMS 可以通过读取索引 - 这将比读取表行更快并且需要更少的 I/O 操作。 OTOH,如果索引没有比它所代表的表更紧凑并且索引没有覆盖(即查询中的所有术语都可以从索引中得到满足),那么您将获得比没有索引更差的性能 - 因为 DBMS 必须执行在每次匹配后进行额外的查找和读取操作以获取数据 - 实际上,DBMS 很可能在没有明确提示的情况下永远不会使用这样的索引。
【解决方案2】:
不。带有正则表达式的 where 子句不会为列使用索引。但是,索引适用于 LIKE 'foo%',因此您可以使用它来缩小结果范围。
【解决方案3】:
看起来有一些选择...
PostgreSQL 有一个名为 pg_trgm 的模块用于快速相似性搜索,包括正则表达式搜索。它提供基于三元组的索引。“从 PostgreSQL 9.3 开始,这些索引类型还支持正则表达式匹配(~ 和 ~* 运算符)的索引搜索”。 PostgreSQL 正则表达式实际上非常强大。
http://www.postgresql.org/docs/current/interactive/pgtrgm.html
Lucene 是一个免费的库,如果你认为它是一个数据库,它可以做到这一点。 Lucene 可以为同一个值创建多种类型的索引,当执行正则表达式搜索时,它使用它们来缩小搜索范围。分析正则表达式,如果是,则执行前缀搜索或后缀搜索,否则使用三元索引来缩小行范围。