1

数据库索引旨在使查找更快,但是在索引列的 where 子句中使用正则表达式的查询的性能如何。

假设我们有一个FILES包含字段的表,FILE_NAME并且我们在 FILE_NAME 上创建了一个索引。

然后我们有一个查询来搜索具有匹配名称模式的文件

SELECT * FROM FILES WHERE FILE_NAME RLIKE regexp

在 FILE_NAME 上创建索引是否有助于提高上述查询的性能?

4

3 回答 3

4

是的,它可能会提高性能——但不是你想的那样。

在正常使用中,索引允许 DBMS 在表中查找行而无需扫描每个条目 - 它可以跳过一些(对于范围比较、特定值和部分匹配,例如LIKE 'ABC%'不适用于带有 的查询LIKE '%XYZ')。当您尝试使用数据的某种转换来查找行时(尽管有语法,RLIKE 是一个基于操作数而不是运算符的函数),DBMS 必须将转换应用于表的每一行。一些 DBMS(例如 Oracle)支持基于函数的索引,因此只要您的正则表达式是恒定的,您就可以根据正则表达式匹配定义一个索引 - MariaDB 支持可以被索引的虚拟列,这相当于同一件事。

因此,在此处使用索引不会减少 DBMS 为了过滤查询而必须获取的行数。

但是,如果匹配数相对于基础数据中的行数较低,并且索引的宽度相对于表行的宽度较小,那么 DBMS 可以通过从索引中读取来识别匹配行 -这将比读取表行更快并且需要更少的 I/O 操作。OTOH 如果索引没有比它所代表的表更紧凑并且索引没有覆盖(即查询中的所有术语都可以从索引中得到满足),那么您将获得比没有索引更差的性能 - 因为 DBMS 必须执行在每次匹配后进行额外的查找和读取操作以获取数据 - 实际上,DBMS 很可能在没有明确提示的情况下永远不会使用这样的索引。

于 2013-11-11T00:34:34.923 回答
1

没有。带有正则表达式的 where 子句不会为列使用索引。但是,索引适用于 a LIKE 'foo%',因此您可以使用它来缩小结果范围。

于 2013-11-11T00:18:53.177 回答
1

看起来有一些选项...... PostgreSQL 有一个名为 pg_trgm 的模块,用于快速相似性搜索,包括正则表达式搜索。它提供基于三元组的索引。“从 PostgreSQL 9.3 开始,这些索引类型还支持正则表达式匹配(~ 和 ~* 运算符)的索引搜索”。PostgreSQL 正则表达式实际上非常强大。 http://www.postgresql.org/docs/current/interactive/pgtrgm.html

Lucene 是一个免费的库,如果你认为它是一个数据库,它可以做到这一点。Lucene 可以为同一个值创建多种类型的索引,当执行正则表达式搜索时,它使用它们来缩小搜索范围。分析正则表达式,如果是,则执行前缀搜索或后缀搜索,否则使用三元组索引来缩小行的范围。

于 2016-03-18T14:47:02.963 回答