1

这个查询运行很慢。为什么?其他都很好。我认为索引很好。

explain analyze 
select "e_inst"."si_id" as "c0" 
from "e_inst" as "e_inst" 
group by "e_inst"."si_id" 
order by "e_inst"."si_id" ASC NULLS LAST

查询计划:

Sort  (cost=12221.87..12221.90 rows=68 width=4) (actual time=1115.377..1115.433 rows=81 loops=1)
  Sort Key: si_id
  Sort Method: quicksort  Memory: 28kB
  ->  HashAggregate  (cost=12221.25..12221.45 rows=68 width=4) (actual time=1115.198..1115.261 rows=81 loops=1)
        ->  Seq Scan on e_inst  (cost=0.00..11920.07 rows=602357 width=4) (actual time=0.021..611.570 rows=602357 loops=1)
Total runtime: 1115.538 ms

创建表和索引:

CREATE TABLE e_inst (
    id integer NOT NULL,
    ip numeric,
    gu character varying,
    referrer character varying,
    proc integer,
    loke_id integer,
    top_id integer,
    si_id integer,
    kop integer,
    count integer,
    created integer,
    modified integer,
    timepop integer,
    count_active character varying,
    country character(3),
    info character varying
);

CREATE INDEX "topEnhance" ON e_inst USING btree (created, top_id);
CREATE INDEX "procEnhance" ON e_inst USING btree (created, proc);
CREATE INDEX "countryEnhance" ON e_install USING btree (created, country);
CREATE INDEX "createdE" ON e_inst USING btree (created);
ALTER TABLE e_inst CLUSTER ON "createdE";
CREATE INDEX "lokeE" ON e_inst USING btree (loke_id);
CREATE INDEX "lokeEnhance" ON e_inst USING btree (created, loke_id);
CREATE INDEX "siE" ON e_inst USING btree (si_id);
CREATE INDEX "siEnhance" ON e_inst USING btree (created, si_id);
CREATE INDEX "kopEnhance" ON e_inst USING btree (created, kop);
4

2 回答 2

3

处理整个表的查询不会使用索引。

事实上,您正在检索和处理600k 条记录。它在一秒钟多一点的时间里就做到了,这实际上是令人印象深刻的。

现在在这种情况下,您尝试从 600k 记录中提取 81 个不同的值。您可能想要做的是构造一个递归查询,以便它获取一行 81 次。这可能会更快,但不能保证。通常我在返回的行数少得多的地方使用这些。然而,这里有一个例子:

WITH RECURSIVE sparse_scan AS (
    SELECT min(si_id) as si_id FROM e_inst
    UNION ALL
    SELECT min(si_id) as si_id
      FROM e_inst
      JOIN (select max(si_id) as last FROM sparse_scan) s
     WHERE s.last < si_id
)
SELECT si_id as c0 FROM sparse_scan;

请注意,这会将顺序扫描替换为 81 次索引扫描。

于 2013-03-21T02:52:16.903 回答
0

升级到 PostgreSQL 9.2。现在是仅索引扫描!效果很好,感谢 a_horse_with_no_name 建议我升级。

于 2013-03-21T22:56:23.410 回答