Sql 通配符或“通配符”;“在列表中”;在Postgres中查询时

Sql 通配符或“通配符”;“在列表中”;在Postgres中查询时,sql,postgresql,query-optimization,wildcard,Sql,Postgresql,Query Optimization,Wildcard,我有一些表格需要获取与foo相关的数据。表的大小约为10^8行 所以我需要从这些表中获取列包含子字符串“foo”的所有行 select * from bar where my_col like '%foo%'; 我知道这很慢,所以我检查了可能的值: select distinct my_col from bar where my_col like '%foo%'; -- => ('xx_foo', 'yy_foo', 'xx_foo_xx', 'foo' ... 'xx_foo_yy')

我有一些表格需要获取与foo相关的数据。表的大小约为10^8行

所以我需要从这些表中获取列包含子字符串“foo”的所有行

select * from bar where my_col like '%foo%';
我知道这很慢,所以我检查了可能的值:

select distinct my_col from bar where my_col like '%foo%';
-- => ('xx_foo', 'yy_foo', 'xx_foo_xx', 'foo' ... 'xx_foo_yy')
可能值的数量在3到20之间变化

现在“%foo%”到底有多慢

select * from bar where my_col like '%foo%';
-- or
select * from bar where my_col in('foo', 'xx_foo' ... 'foo_yy'); -- list_size = 20
关于何时使用什么的一般规则,或者测试不同情况下的速度是唯一的方法吗


编辑:我不拥有该表,并且foo列上不存在索引。因此,无论发生什么情况,它都需要进行一次完整的表扫描。

如果使用
%foo%
,您将得到一次完整的表扫描,这很慢

如果将中的
与值列表一起使用,则可以使用索引(如果该索引存在于具有条件的列上)


因此,如果您能够,您应该避免使用
%foo%
。根据表中新值可能出现的频率,您可以考虑使用一个额外的表来保存不同的值并在查询主表时使用它,并在新的不同值出现时更新该额外表(如果在设计中是可能的).

当模式以
%
开头时,使用
like
操作符进行搜索肯定会导致表格扫描。如果在
运算符中使用
,且值不超过表中值的百分之几,则可以使用索引(如果存在)。检查基数概念:


DBMS知道保留表统计信息的基数。如果列具有较高的基数和索引,则在使用
in
运算符时可能会进行索引扫描。要更新统计信息,请发出
analyze
命令。

Ohh,忘了提及我现在拥有该表,并且我不太可能影响该列上的任何索引创建。