数据库索引旨在使查找更快,但是在索引的列的where子句中使用正则表达式的查询的性能如何。
假设我们有一个表FILES
,其中包含一个字段FILE_NAME
,我们在FILE_NAME上创建了一个索引。
然后我们查询搜索具有匹配名称模式的文件
SELECT * FROM FILES WHERE FILE_NAME RLIKE regexp
在FILE_NAME上创建索引有助于提高上述查询的性能吗?
答案 0 :(得分:4)
是的,可以提高效果 - 但不是你想的那样。
在正常使用中,索引允许DBMS在不扫描每个条目的情况下查找表中的行 - 它可以跳过一些(用于范围比较,特定值和部分匹配,例如LIKE 'ABC%'
但不用于LIKE '%XYZ'
的查询。当您尝试使用某些数据转换查找行时(尽管语法,RLIKE是基于操作数而不是操作符的函数),DBMS必须将转换应用于表的每一行。一些DBMS(例如Oracle)支持基于函数的索引,因此只要您的正则表达式是常量,您就可以基于正则表达式匹配来定义索引 - MariaDB支持可以被索引的虚拟列,这些列相同。
因此,在此处使用索引不会减少DBMS为了过滤查询而必须获取的行数。
但是,如果匹配数相对于基础数据中的行数较低,并且索引的宽度相对于表行的宽度相对较小,则DBMS可以通过读取来识别匹配的行索引 - 与读取表行相比,速度更快,所需的I / O操作更少。 OTOH如果索引没有比它所代表的表更紧凑并且索引没有覆盖(即查询中的所有术语都可以从索引中得到满足),那么你将获得比没有索引更糟糕的性能 - 因为DBMS必须执行在每次匹配之后进行额外的搜索和读取操作以获取数据 - 实际上,如果没有明确的提示,DBMS可能永远不会使用这样的索引。
答案 1 :(得分:1)
不。带有正则表达式的where子句不会使用该列的索引。但是,索引适用于LIKE 'foo%'
,因此您可以使用它来缩小结果范围。
答案 2 :(得分:1)
看起来有一些选择...... PostgreSQL有一个名为pg_trgm的模块,用于快速相似性搜索,包括正则表达式搜索。它提供了基于trigram的索引。“从PostgreSQL 9.3开始,这些索引类型还支持索引搜索正则表达式匹配(〜和〜*运算符)”。 PostgreSQL正则表达式实际上非常强大。 http://www.postgresql.org/docs/current/interactive/pgtrgm.html
Lucene是一个免费的图书馆,如果你认为它是一个数据库。 Lucene可以为相同的值创建多种类型的索引,并且在执行正则表达式搜索时,它使用它们来缩小搜索范围。分析正则表达式,如果是这种情况,则执行前缀搜索或后缀搜索,否则使用trigram索引缩小行。