【发布时间】:2018-05-13 21:15:52
【问题描述】:
我正在使用:Rails 3.2.13 和 PostgreSQL 9.4.7
我有 2 个产品表,AProducts 和 BProducts. 两个表都有一个 category_id 整数,它是一个索引列,并且两个表都有几百万条记录。
当我通过category_id查询AProducts时,响应很快并且使用索引,但是当我查询BProducts时响应非常非常慢,并且它使用顺序扫描而不是使用索引。我试图弄清楚为什么BProducts 会发生这种情况,因为表格和模型与AProducts 几乎相同。以下是 EXPLAIN 的结果:
irb(main):2290:0> BProduct.where(:category_id => 700).explain
BProduct Load (219696.7ms) SELECT "b_products".* FROM "b_products" WHERE "b_products"."category_id" = 700
EXPLAIN (1.3ms) EXPLAIN SELECT "b_products".* FROM "b_products" WHERE "b_products"."category_id" = 700
=> "EXPLAIN for: SELECT \"b_products\".* FROM \"b_products\" WHERE \"b_products\".\"category_id\" = 700\n QUERY PLAN\n-----------------------------------------------------------------------------\n Seq Scan on b_products (cost=0.00..1791663.25 rows=926 width=2036)\n Filter: (category_id = 700)\n(2 rows)\n"
上面的慢查询耗时 219696.7ms,并且不使用索引。下面对 AProduct 的查询很快,并且确实使用了索引。
irb(main):2289:0> AProduct.where(:category_id => 700).explain
AProduct Load (51.0ms) SELECT "a_products".* FROM "a_products" WHERE "a_products"."category_id" = 700
EXPLAIN (1.2ms) EXPLAIN SELECT "a_products".* FROM "a_products" WHERE "a_products"."category_id" = 700
=> "EXPLAIN for: SELECT \"a_products\".* FROM \"a_products\" WHERE \"a_products\".\"category_id\" = 700\n QUERY PLAN\n--------------------------------------------------------------------------------------------------------------------------------\n Index Scan using index_a_products_on_category_id on a_products (cost=0.56..5448.33 rows=1359 width=883)\n Index Cond: (category_id = 700)\n(2 rows)\n"
我想弄清楚的是,如何让我的 BProduct 查找使用索引并以与 AProduct 相同的速度获取记录,为什么这不是我看到的默认行为?
【问题讨论】:
-
您可以运行
psql并输入\d a_products和\d b_products并确保索引完全相同 -
两个表都有一个索引:
"index_b_products_on_category_id" btree (category_id)和"index_a_products_on_category_id" btree (category_id) -
好的,有一些原因,为什么 PG 不在大表上使用索引。您可以尝试使用
VACUUM ANALYZEpg SQL 命令,然后再次检查计划。 -
那你可以试试
/*+ IndexScan(b_products) */ SELECT "b_products".* FROM "b_products" ... -
如果没有结果,请仅使用
postgresql标签提出此问题,并提供两个表的表结构和行数。准备好提供有关 PG 配置和服务器参数(内存)的信息
标签: ruby-on-rails postgresql ruby-on-rails-3 postgresql-9.4