2

これは私のクエリです:

explain analyze SELECT levenshtein('google', lower(s."Name"), 2, 2, 1), d."Domain"
FROM   analyst_sld s, analyst_domain d
WHERE  levenshtein('google', lower(s."Name"), 2, 2, 1) < 4 AND s.id = d."SLDk_id"
ORDER  BY 1;

これは出力です:

                                                                  QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------------------
 Sort  (cost=5340874.17..5383497.72 rows=17049420 width=46) (actual time=136245.943..138709.585 rows=1022346 loops=1)
   Sort Key: (levenshtein('google'::text, lower((s."Name")::text), 2, 2, 1))
   Sort Method:  external sort  Disk: 78656kB
   ->  Hash Join  (cost=122111.24..1195078.39 rows=17049420 width=46) (actual time=16730.865..133020.419 rows=1022346 loops=1)
         Hash Cond: (d."SLDk_id" = s.id)
         ->  Seq Scan on analyst_domain d  (cost=0.00..417631.20 rows=17049420 width=38) (actual time=0.036..64677.170 rows=17041042 loops=1)
         ->  Hash  (cost=103151.93..103151.93 rows=1090665 width=16) (actual time=16730.443..16730.443 rows=1071 loops=1)
               ->  Seq Scan on analyst_sld s  (cost=0.00..103151.93 rows=1090665 width=16) (actual time=14.742..16726.358 rows=1071 loops=1)
                     Filter: (levenshtein('google'::text, lower(("Name")::text), 2, 2, 1) < 4)
 Total runtime: 139557.853 ms

インデックスではなくシーケンシャル スキャンを使用するのはなぜですか? また、「Hash Join」と「Hash Cond」とはどういう意味ですか?

EDIT_1: インデックス:

                                      Table "public.analyst_domain"
     Column     |           Type           |                          Modifiers
----------------+--------------------------+-------------------------------------------------------------
 ID             | integer                  | not null default nextval('analyst_domain_id_seq'::regclass)
 Domain         | character varying(255)   | not null
 SLDk_id        | integer                  |
Indexes:
    "analyst_domain_pkey" PRIMARY KEY, btree ("ID")
    "analyst_domain_Domain_key" UNIQUE, btree ("Domain")
    "analyst_domain_sldk" btree ("SLDk_id")



                                      Table "public.analyst_sld"
     Column     |           Type           |                        Modifiers
----------------+--------------------------+----------------------------------------------------------
 id             | integer                  | not null default nextval('analyst_sld_id_seq'::regclass)
 Name           | character varying(255)   | not null
Indexes:
    "analyst_sld_pkey" PRIMARY KEY, btree (id)
    "analyst_sld_Name_key" UNIQUE, btree ("Name") CLUSTER
    "analyst_sld_upper_idx" btree (upper("Name"::text))
4

3 に答える 3

2

レーベンシュタイン フィルタリングを行う唯一の方法であるため、analyst_sld でシーケンシャル スキャンを使用します。それが重要なフィルターであると思われる場合は、次のことができます

CREATE INDEX lev_index on 
 analyst_sld (levenshtein('google', lower("Name"), 2, 2, 1));

ハッシュに関する限り: Postgres は、テーブルを結合する最善の方法は、結合列で等しいハッシュを探すことであると判断しました (バケットに複数のエントリがある場合はそれらを解決します)。テーブルにはいくつの要素があり、結合はどれくらいの大きさになると予想されますか?

于 2012-08-15T20:27:36.067 に答える
1

DDL について: pgAdmin III で - ツリーでオブジェクト (テーブル/インデックス/etc) を選択すると、右側のウィンドウに DDL が表示されます。

DDL は、以下の仮定に基づく推測よりも優れた回答を可能にします。

理由については、与えられた情報と結合基準の主キー インデックスを仮定すると、ここに私の推測があります。そのフィルターの選択性に関するアイデア。s.name の行ルックアップを伴うインデックス スキャンとシーケンシャル スキャンのどちらが速いですか? オプティマイザーによると、シーケンシャル ウィン。

于 2012-08-15T20:32:22.000 に答える
0

私は PostgreSQL の専門家ではありませんが、levenshtein 関数を使用しているため、順次スキャンを使用しているようです。この関数の詳細はわかりませんが、通常は関数の評価に基づいてインデックスを作成できます。ただし、あなたの場合、「Google」文字列が可変であると推測するのは危険なので、インデックスがどれほど役立つかはわかりません...

于 2012-08-15T19:49:03.140 に答える