Nic*_*ick 24 mysql postgresql performance full-text-search pattern-matching
谁能解释一下 LIKE 运算符是如何在当前数据库系统(例如 MySQL 或 Postgres)中实现的?或者指出一些解释它的参考资料?
天真的方法是检查每条记录,在感兴趣的字段上执行正则表达式或部分字符串匹配,但我有一种感觉(希望)这些系统做一些更聪明的事情。
Erw*_*ter 29
除了 Justin Cave 所写的内容之外,从PostgreSQL 9.1 开始,您可以使用( ) 或( )加快任何搜索速度,也可以LIKE( ~~)加快基本的正则表达式匹配。使用带有 GIN 或 GiST 索引的模块pg_trgm提供的运算符类来加速非左锚定的表达式。要安装扩展,请为每个数据库运行一次:ILIKE~~*~LIKE
CREATE EXTENSION pg_trgm;
Run Code Online (Sandbox Code Playgroud)
创建表单的索引
CREATE INDEX tbl_col_gin_trgm_idx ON tbl USING gin (col gin_trgm_ops);
Run Code Online (Sandbox Code Playgroud)
或者:
CREATE INDEX tbl_col_gist_trgm_idx ON tbl USING gist (col gist_trgm_ops);
Run Code Online (Sandbox Code Playgroud)
创建和维护GIN 或 GiST 索引会带来成本,但如果您的表没有大量写入,这对您来说是一个很棒的功能。
GiST 和 GIN 索引之间的选择取决于 GiST 和 GIN 的相对性能特征,这在别处讨论。根据经验,GIN 索引的搜索速度比 GiST 索引快,但构建或更新速度较慢;所以 GIN 更适合静态数据,而 GiST 更适合经常更新的数据。
但是对于使用距离运算符的“最近邻居”类型的查询<->:
这可以通过 GiST 索引非常有效地实现,但不能通过 GIN 索引实现。
Jus*_*ave 20
不,这几乎就是他们正在做的事情。现在,如果没有前导通配符并且该字段被索引,这是通常的情况,数据库引擎可以将正则表达式应用于索引。所以,例如,如果你写
SELECT *
FROM employees
WHERE last_name LIKE 'Cav%'
Run Code Online (Sandbox Code Playgroud)
数据库可以使用索引LAST_NAME来查找姓氏以“Cav”开头的所有行。另一方面,如果你有类似的东西
SELECT *
FROM employees
WHERE last_name LIKE '%av%'
Run Code Online (Sandbox Code Playgroud)
数据库必须扫描整个表(或整个索引)并根据完整LAST_NAME值评估表达式。显然,这是非常昂贵的。
大多数更好的关系数据库都可以通过构建不同种类的索引和文本目录以更有效的方式进行全文搜索,但这些不使用 LIKE 关键字。例如,这里有一篇很好的文章,讨论了 PostgreSQL 中的全文搜索。
说到 MySQL,通配符 (%) 的位置有所不同。如果文本的第一部分指定为where first_name like 'Sta%',那么数据库引擎将只搜索以 S 开头的单词的较小子集,然后转到 St,然后是 Sta 等。如果您执行类似的操作where first_name like '%stan%',则和整个扫描列将是必需的。您还可以查看也进行自然语言搜索的全文索引。在此处查看 MySQL 文档。
| 归档时间: |
|
| 查看次数: |
10354 次 |
| 最近记录: |