Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance 为什么我的Postgres SQL查询不使用索引_Performance_Postgresql_Postgresql 9.2_Heroku Postgres - Fatal编程技术网

Performance 为什么我的Postgres SQL查询不使用索引

Performance 为什么我的Postgres SQL查询不使用索引,performance,postgresql,postgresql-9.2,heroku-postgres,Performance,Postgresql,Postgresql 9.2,Heroku Postgres,我有一张约2300万行的销售积分表。它在store_id、book_id上有一个b树索引。我希望下面的查询使用该索引,但EXPLAIN表明它正在进行顺序扫描: select distinct store_id, book_id from sales_points 以下是EXPLAIN的输出: Unique (cost=2050448.88..2086120.31 rows=861604 width=8) -> Sort (cost=2050448.88..2062339.35

我有一张约2300万行的销售积分表。它在store_id、book_id上有一个b树索引。我希望下面的查询使用该索引,但EXPLAIN表明它正在进行顺序扫描:

select distinct store_id, book_id from sales_points
以下是EXPLAIN的输出:

Unique  (cost=2050448.88..2086120.31 rows=861604 width=8)
  ->  Sort  (cost=2050448.88..2062339.35 rows=23780957 width=8)
        Sort Key: store_id, book_id
        ->  Seq Scan on sales_points  (cost=0.00..1003261.87 rows=23780957 width=8)
如果我这样做,它会使用索引:

select distinct book_id from sales_points where store_id = 1
以下是此查询的解释输出:

HashAggregate  (cost=999671.02..999672.78 rows=587 width=4)
  ->  Bitmap Heap Scan on sales_points  (cost=55576.17..998149.04 rows=3043963 width=4)
        Recheck Cond: (store_id = 1)
        ->  Bitmap Index Scan on index_sales_points_on_store_id_and_book_id  (cost=0.00..55423.97 rows=3043963 width=0)
              Index Cond: (store_id = 1)
以下是DDL表:

CREATE TABLE sales_points
(
  id serial NOT NULL,
  book_id integer,
  store_id integer,
  date date,
  created_at timestamp without time zone,
  updated_at timestamp without time zone,
  avg_list_price numeric(5,2),
  royalty_amt numeric(9,2),
  currency character varying(255),
  settlement_date date,
  paid_sales integer,
  paid_returns integer,
  free_sales integer,
  free_returns integer,
  lent_units integer,
  lending_revenue numeric(9,2),
  is_placeholder boolean,
  distributor_id integer,
  source1_id integer,
  source2_id integer,
  source3_id integer,
  CONSTRAINT sales_points_pkey PRIMARY KEY (id)
)
WITH (
  OIDS=FALSE
);
以下是索引表达式:

CREATE INDEX index_sales_points_on_store_id_and_book_id
  ON sales_points
  USING btree
  (store_id, book_id);

那么为什么Postgres不使用索引来加速选择呢?

好吧,我认为你的索引在需要的时候可以正常工作。您的第一个查询没有WHERE子句,因此Postgres无论如何都必须检索表中的所有记录

仅用于测试,您可以通过禁用顺序扫描强制使用索引:

SET enable_seqscan = OFF;
Postgres根据varoius条件选择其扫描计划。摘自:

…当不使用索引时,强制使用索引对测试非常有用。有一些运行时参数可以关闭各种计划类型。例如,关闭顺序扫描启用_seqscan和嵌套循环联接启用_nestloop(最基本的计划)将强制系统使用不同的计划。如果系统仍然选择顺序扫描或嵌套循环联接,那么可能有一个更根本的原因导致没有使用索引


第一个查询只能通过查看索引返回,9.2确实有索引扫描。所以这个问题有点正确。@a_horse_,没有名字,我没有说这不是一个正确的问题;我指的是你的声明Postgres必须检索表中的所有记录-它也可以是索引。表的定义是什么?你能发布DDL吗?