Postgres 索引对原始 SQL 与 ActiveRecord 查询的影响截然不同
Postgres index has massively different impact on raw SQL vs ActiveRecord query
我有一个包含 150k 个名字的 table,并尝试向 lower(name)
添加索引以加快查找速度。索引将原始 SQL 查询速度提高了大约 x100,但使用 ActiveRecord 执行的相同查询不受影响,如果不是慢一点的话。
这些是查询:
NamedEntity.where("lower(name) = ?", "John Doe".downcase).first
对比
conn.execute(
%q{SELECT "named_entities".* FROM "named_entities" WHERE (lower(name) = 'john doe');}
)
我用
添加了索引
CREATE INDEX index_named_entities_on_lower_name ON named_entities USING btree (lower(name));
以下是比较所有案例的基准(每个案例执行 50 次):
no index, AR: 6.999421
with index, AR: 7.264234
no index, SQL: 5.569600
with index, SQL: 0.045464
AR 和 SQL 的查询计划完全相同。
没有索引:
Seq Scan on named_entities (cost=0.00..2854.31 rows=785 width=130)
Filter: (lower((name)::text) = 'john doe'::text)
并带有索引:
Bitmap Heap Scan on named_entities (cost=9.30..982.51 rows=785 width=130)
Recheck Cond: (lower((name)::text) = 'john doe'::text)
-> Bitmap Index Scan on index_named_entities_on_lower_name (cost=0.00..9.26 rows=785 width=0)
Index Cond: (lower((name)::text) = 'john doe'::text)
我不知道该如何解释。 ActiveRecord 增加的开销应该不受索引的影响,所以索引和无索引之间的 速度差异 对于 AR 和 SQL 应该是相同的,不是吗?
我找到了解决问题的方法,方法是在创建索引后添加 ANALYZE named_entities;
。这使得 Postgres 更新其关于各种事物的统计信息,因此它可以生成更好的查询计划。 (还发现Postgres docs很厉害。)
这仍然不能解释时间差异,因为 explain
s 表明 SQL 和 AR 查询导致相同的慢查询计划。
我有一个包含 150k 个名字的 table,并尝试向 lower(name)
添加索引以加快查找速度。索引将原始 SQL 查询速度提高了大约 x100,但使用 ActiveRecord 执行的相同查询不受影响,如果不是慢一点的话。
这些是查询:
NamedEntity.where("lower(name) = ?", "John Doe".downcase).first
对比
conn.execute(
%q{SELECT "named_entities".* FROM "named_entities" WHERE (lower(name) = 'john doe');}
)
我用
添加了索引CREATE INDEX index_named_entities_on_lower_name ON named_entities USING btree (lower(name));
以下是比较所有案例的基准(每个案例执行 50 次):
no index, AR: 6.999421
with index, AR: 7.264234
no index, SQL: 5.569600
with index, SQL: 0.045464
AR 和 SQL 的查询计划完全相同。
没有索引:
Seq Scan on named_entities (cost=0.00..2854.31 rows=785 width=130)
Filter: (lower((name)::text) = 'john doe'::text)
并带有索引:
Bitmap Heap Scan on named_entities (cost=9.30..982.51 rows=785 width=130)
Recheck Cond: (lower((name)::text) = 'john doe'::text)
-> Bitmap Index Scan on index_named_entities_on_lower_name (cost=0.00..9.26 rows=785 width=0)
Index Cond: (lower((name)::text) = 'john doe'::text)
我不知道该如何解释。 ActiveRecord 增加的开销应该不受索引的影响,所以索引和无索引之间的 速度差异 对于 AR 和 SQL 应该是相同的,不是吗?
我找到了解决问题的方法,方法是在创建索引后添加 ANALYZE named_entities;
。这使得 Postgres 更新其关于各种事物的统计信息,因此它可以生成更好的查询计划。 (还发现Postgres docs很厉害。)
这仍然不能解释时间差异,因为 explain
s 表明 SQL 和 AR 查询导致相同的慢查询计划。