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

インデックスは、テーブル全体を処理するクエリでは使用されません。

実際には、 60 万件のレコードを取得して処理しています。これをわずか 1 秒強で実行できるというのは、実際にはちょっと印象的です。

この場合、600k レコードから 81 個の個別の値を抽出しようとしています。やりたいことは、1 つの行を 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 に答える