LIKE如何实施?


22

谁能解释一下LIKE运算符如何在当前数据库系统(例如MySQL或Postgres)中实现?还是让我参考一些解释它的参考文献?

天真的方法是检查每条记录,在感兴趣的字段上执行正则表达式或部分字符串匹配,但是我有一种感觉(希望),这些系统做得更聪明。

Answers:


19

不,那几乎就是他们在做什么。现在,如果没有前导通配符并且对该字段建立了索引(这是通常的情况),则数据库引擎可以将正则表达式应用于索引。因此,例如,如果您写

SELECT *
  FROM employees
 WHERE last_name LIKE 'Cav%'

数据库可以使用索引on LAST_NAME查找姓氏以'Cav'开头的所有行。另一方面,如果您有类似

SELECT *
  FROM employees
 WHERE last_name LIKE '%av%'

数据库将不得不扫描整个表(或整个索引),并根据完整LAST_NAME值评估表达式。显然,这非常昂贵。

大多数更好的关系数据库都具有通过构建不同种类的索引和文本目录,以更有效的方式进行全文搜索的功能,但是它们不使用LIKE关键字。例如,这是一篇不错的文章,讨论了PostgreSQL中的全文本搜索


4
Oracle甚至可以使用前导百分比的索引。如果要搜索的数据表示行的一小部分,则提示可以强制其使用索引并加快执行速度。参见laurentschneider.com/wordpress/2009/07/…
Leigh Riffel

1
“扫描整个表...显然,这非常昂贵” –取决于表;)ps您是否同意LAST_NAME成为聚簇索引(第一列)的候选人?pps该答案在多大程度上假定数据库系统基于磁盘和B树索引上的连续存储?
一天,2012年

26

除了Justin Cave撰写的内容之外,自PostgreSQL 9.1起,您可以使用()或()以及基本正则表达式匹配()来加快任何搜索的速度。将pg_trgm模块提供的运算符类与GIN或GiST索引一起使用,可以加快非左锚表达式的速度。要安装扩展,请对每个数据库运行一次:LIKE~~ILIKE~~*~LIKE

CREATE EXTENSION pg_trgm;

创建表单的索引

CREATE INDEX tbl_col_gin_trgm_idx ON tbl USING gin (col gin_trgm_ops);

要么:

CREATE INDEX tbl_col_gist_trgm_idx ON tbl USING gist (col gist_trgm_ops);

创建和维护GIN或GiST索引需要付出一定的代价,但是如果您的表没有被大量编写,那么这对您来说是一个很棒的功能。

Depesz在他的博客中写了一篇关于新功能的出色文章

GIN还是GiST?

手册中的这两个引号应提供一些指导

GiST和GIN索引之间的选择取决于GiST和GIN的相对性能特征,这将在其他地方讨论。根据经验,GIN索引的搜索速度比GiST索引要快,但构建或更新速度却较慢;因此GIN更适合静态数据,而GiST更适合经常更新的数据。

但是对于使用“距离”运算符的“最近邻居”类型的查询<->

这可以通过GiST索引非常有效地实现,而不能通过GIN索引有效地实现。


3
读这篇文章,我想知道是否要使用GIN或GiST。根据我的阅读,GIN索引的维护成本较高,但搜索速度更快,而GiST索引的维护成本较低,但搜索速度较慢。这意味着GIN索引通常应在相对静态的数据上使用,而GiST索引在突变程度更高的表上更可取。
Colin't Hart

1
@ Colin'tHart:通常是这样,但是该规则也有例外。考虑上面的附录。
Erwin Brandstetter

5

说到MySQL,通配符(%)的位置会有所不同。如果像指定文本的第一部分where first_name like 'Sta%',那么DB引擎只搜索词用在看我们,然后去圣,一个较小的子,然后站等,如果你这样做where first_name like '%stan%',然后和整个扫描列将是必需的。您还可以查看全文索引,该索引也可以进行自然语言搜索。在此处查看MySQL文档。


1
当子字符串定义为3个字符时,为什么它会开始搜索“ S%”(即我们知道字符串不是“ Sr%”)?还是您假设数据库在属性上具有前缀树并提供了遍历该树的示例?
尼克,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.