【发布时间】:2015-06-10 15:17:23
【问题描述】:
有人能解释一下这些 SQL 之间如此大的性能差异吗?
SELECT count(*) as cnt FROM table WHERE name ~ '\*{3}'; -- Total runtime 12.000 - 18.000 ms
SELECT count(*) as cnt FROM table WHERE name ~ '\*\*\*'; -- Total runtime 12.000 - 18.000 ms
SELECT count(*) as cnt FROM table WHERE name LIKE '%***%'; -- Total runtime 5.000 - 7.000 ms
如您所见,LIKE 运算符和简单正则表达式之间的差异不止一倍(我认为 LIKE 运算符内部会转换为正则表达式,应该没有任何区别)
那里有将近 13000 行,“名称”列是“文本”类型。没有与表中定义的“名称”列相关的索引。
编辑:
解释他们每个人的分析:
EXPLAIN ANALYZE SELECT count(*) as cnt FROM datos WHERE nombre ~ '\*{3}';
Aggregate (cost=894.32..894.33 rows=1 width=0) (actual time=18.279..18.280 rows=1 loops=1)
-> Seq Scan on datos (cost=0.00..894.31 rows=1 width=0) (actual time=0.620..18.266 rows=25 loops=1)
Filter: (nombre ~ '\*{3}'::text)
Total runtime: 18.327 ms
EXPLAIN ANALYZE SELECT count(*) as cnt FROM datos WHERE nombre ~ '\*\*\*';
Aggregate (cost=894.32..894.33 rows=1 width=0) (actual time=17.404..17.405 rows=1 loops=1)
-> Seq Scan on datos (cost=0.00..894.31 rows=1 width=0) (actual time=0.608..17.396 rows=25 loops=1)
Filter: (nombre ~ '\*\*\*'::text)
Total runtime: 17.451 ms
EXPLAIN ANALYZE SELECT count(*) as cnt FROM datos WHERE nombre LIKE '%***%';
Aggregate (cost=894.32..894.33 rows=1 width=0) (actual time=4.258..4.258 rows=1 loops=1)
-> Seq Scan on datos (cost=0.00..894.31 rows=1 width=0) (actual time=0.138..4.249 rows=25 loops=1)
Filter: (nombre ~~ '%***%'::text)
Total runtime: 4.295 ms
【问题讨论】:
-
请显示
explain analyze。 -
@CraigRinger 我在问题文本中添加了对每个查询的解释分析
-
运行正则表达式比较比应用虚拟
LIKE格式更昂贵。 -
@dmikam 我不同意 - 正则表达式更难解析且更难应用。如果您不同意我的观点 - 尝试同时实现
LIKE和 PCRE 兼容引擎。然后比较哪个更费力,工作更慢。 “只匹配以 *** 结尾的字符串”---不,那里也有空格。 -
这三个查询占用空间小,完全由内存/缓冲区提供服务。这就是为什么 CPU 成本在总成本中占主导地位的原因。一旦必须从磁盘中提取数据,成本将主要由搜索时间和 I/O 支配,查询的执行大致相同。 (至少:这是我所期望的)
标签: sql regex postgresql performance sql-like