LIKE
不带通配符等同于=
. 假设您实际上是说name = 'text'
.
索引是性能的关键。
测试设置
CREATE TABLE image (
image_id serial PRIMARY KEY
, group_id int NOT NULL
, name text NOT NULL
);
理想情况下,您创建两个索引(除了主键):
CREATE INDEX image_name_grp_idx ON image (name, group_id);
CREATE INDEX image_grp_idx ON image (group_id);
第二个可能不是必需的,具体取决于数据分布和其他细节。这里的解释:
询问
对于您的情况,这应该是最快的查询:
SELECT * FROM image WHERE name = 'name105' AND group_id = 10
UNION ALL
SELECT * FROM image WHERE name = 'name105'
UNION ALL
SELECT * FROM image WHERE group_id = 10
LIMIT 1;
SQL小提琴。
该LIMIT
子句适用于整个查询。Postgres 足够聪明,一旦找到足够的行来满足. 因此,对于第一个查询中的匹配,输出如下所示(向右滚动!):UNION ALL
LIMIT
SELECT
EXPLAIN ANALYZE
限制(成本=0.00..0.86 行=1 宽度=40)(实际时间=0.045..0.046 行=1 循环=1)
缓冲区:本地命中=4
-> 结果(成本=0.00..866.59 行=1002 宽度=40)(实际时间=0.042..0.042 行=1 循环=1)
缓冲区:本地命中=4
-> 追加(成本=0.00..866.59 行=1002 宽度=40)(实际时间=0.039..0.039 行=1 循环=1)
缓冲区:本地命中=4
-> 在图像上使用 image_name_grp_idx 进行索引扫描(成本=0.00..3.76 行=2 宽度=40)(实际时间=0.035..0.035行=1 循环=1)
索引条件:((name = 'name105'::text) AND (group_id = 10))
缓冲区:本地命中=4
-> 在图像上使用 image_name_grp_idx 进行索引扫描(成本=0.00..406.36 行=500 宽度=40)(从未执行)
索引条件: (name = 'name105'::text)
-> 在图像上使用 image_grp_idx 进行索引扫描(成本=0.00..406.36 行=500 宽度=40)(从未执行)
指数条件:(group_id = 10)
总运行时间:0.087 毫秒
大胆强调我的。
不要添加子句ORDER BY
,这会使效果无效。然后 Postgres 在返回顶行之前必须考虑所有行。
最后的问题
有没有通用的解决方案?
这是通用解决方案。添加任意数量的SELECT
语句。
当然,当搜索结果按相关性排序时,它会派上用场。
结果中只有一行带有LIMIT 1
。空位排序的一种。