2017-04-12 9 views
1

のPostgreSQL 9.5.0にのPostgres、インデックス

を使用していない単純なクエリは、私はそれが1931964行を持っているmessage_attachmentsと呼ばれるテーブルを持っています。

私がそのテーブルで検索するキーは、message_idです。

また、必ずdeleted_atをNULL文(例:ソフト削除)に含めます。

作成したインデックスがありました:

CREATE INDEX message_attachments_message_id_idx 
    ON message_attachments (message_id) 
WHERE deleted_at IS NULL; 

だから、直接このクエリに一致する必要があります。

EXPLAIN ANALYZE 
select * 
from "message_attachments" 
where "deleted_at" is null 
    and "message_id" = 33998052; 

しかし、結果のクエリプランは次のようになります。

Seq Scan on message_attachments (cost=0.00..69239.91 rows=4 width=149) (actual time=1667.850..1667.850 rows=0 loops=1) 
    Filter: ((deleted_at IS NULL) AND (message_id = 33998052)) 
    Rows Removed by Filter: 1931896 
Planning time: 0.114 ms 
Execution time: 1667.885 ms 

私は」は、私のデータベースからこのようなインデックスを使用していますが、何とかそれはその特定のtaでそれを好きではないようですble。

カーディナリティについては、同じ値の列が最大で5つあります。

また、ANALYZEおよびVACUUM ANALYZEがその表で実行されました。

編集これはそのように見えるそのテーブルの2番目のインデックス、上で今実行していることになる1

SET enable_seqscan to off

SET enable_seqscan to off; EXPLAIN ANALYZE select * from "message_attachments" where "deleted_at" is null and "message_id" = 33998052; 
SET 
                      QUERY PLAN 
----------------------------------------------------------------------------------------------------------------------------------------------------------------- 
Bitmap Heap Scan on message_attachments (cost=36111.83..105378.49 rows=4 width=149) (actual time=2343.361..2343.361 rows=0 loops=1) 
    Recheck Cond: (deleted_at IS NULL) 
    Filter: (message_id = 33998052) 
    Rows Removed by Filter: 1932233 
    Heap Blocks: exact=45086 
    -> Bitmap Index Scan on message_attachments_deleted_at_index (cost=0.00..36111.82 rows=1934453 width=0) (actual time=789.836..789.836 rows=1933784 loops=1) 
     Index Cond: (deleted_at IS NULL) 
Planning time: 0.098 ms 
Execution time: 2343.425 ms 

:(間違い使用するべきではありません)

CREATE INDEX message_attachments_deleted_at_index ON message_attachments USING btree (deleted_at) 

編集2

ホットスタンバイホスト上
\d+ message_attachments 
                 Table "public.message_attachments" 
    Column |   Type    |       Modifiers        | Storage | Stats target | Description 
------------+-----------------------------+------------------------------------------------------------------+----------+--------------+------------- 
id   | bigint      | not null default nextval('message_attachments_id_seq'::regclass) | plain |    | 
created_at | timestamp without time zone | not null               | plain |    | 
updated_at | timestamp without time zone | not null               | plain |    | 
deleted_at | timestamp without time zone |                 | plain |    | 
name  | character varying(255)  | not null               | extended |    | 
filename | character varying(255)  | not null               | extended |    | 
content | bytea      |                 | extended |    | 
hash  | character varying(255)  | not null               | extended |    | 
mime  | character varying(255)  | not null               | extended |    | 
size  | bigint      | not null               | plain |    | 
message_id | bigint      | not null               | plain |    | 
Indexes: 
    "message_attachments_pkey" PRIMARY KEY, btree (id) 
    "message_attachments_deleted_at_index" btree (deleted_at) 
    "message_attachments_message_id_idx" btree (message_id) WHERE deleted_at IS NULL 
Foreign-key constraints: 
    "message_attachments_message_id_foreign" FOREIGN KEY (message_id) REFERENCES messages(id) 

EDIT3

全く同じ行動。

Edit4

select seq_scan,seq_tup_read,idx_scan,idx_tup_fetch,n_live_tup,pg_stat_all_tables.n_dead_tup,last_analyze,pg_stat_all_tables.analyze_count,pg_stat_all_tables.last_autoanalyze from pg_stat_all_tables where relname = 'message_attachments'; 
seq_scan | seq_tup_read | idx_scan | idx_tup_fetch | n_live_tup | n_dead_tup |   last_analyze   | analyze_count |  last_autoanalyze 
----------+----------------+----------+---------------+------------+------------+-------------------------------+---------------+------------------------------- 
18728036 | 26379554229720 | 1475541 |  808566894 | 1934435 |  28052 | 2017-04-12 09:48:34.638184+02 |   68 | 2017-02-02 18:41:05.902214+01 

select * from pg_stat_all_indexes where relname = 'message_attachments'; 
relid | indexrelid | schemaname |  relname  |    indexrelname    | idx_scan | idx_tup_read | idx_tup_fetch 
--------+------------+------------+---------------------+--------------------------------------+----------+--------------+--------------- 
113645 |  113652 | public  | message_attachments | message_attachments_pkey    | 1475563 | 804751648 |  802770401 
113645 |  113659 | public  | message_attachments | message_attachments_deleted_at_index |  3 |  5801165 |    0 
113645 | 20954507 | public  | message_attachments | message_attachments_message_id_idx |  0 |   0 |    0 
+0

することにENABLE_SEQSCAN SET 'てみてくださいオフ "をクリックして再度分析して費用を確認してください –

+0

あなたはどのPostgresバージョンを使用していますか?本当にあなたはテーブルを分析したと思いますか? Postgresが4行しか見積もっていないという事実(テーブルが200万に近くなったとき)は統計が**最新ではないことを示しているようです。 –

+0

@a_horse_with_no_nameは間違いなく奇妙です!私は9.5を使用していて、pg_classの中に1934020個のタプルがあることがわかります.4行の見積もりはどこから来ますか?そして、私は間違いなくVACUUM ANALYZE message_attachmentsを実行しました。メッセージの添付ファイルを解析しました。 –

答えて

0

わかりました(それはup2dateのです)、私はこれを解決しました。

phpで殺されたクエリのために何とかLOCKが掛かっていましたが、数日前にpostgresのプロセスを終了したことはありませんでした。

だから、誰もが同じ問題をexpiriencingために、あなたにLOCKSチェック:

SELECT relation::regclass, * FROM pg_locks WHERE NOT GRANTED; 

もが、数日前から開いているすべての接続がある場合:

select * from pg_stat_activity order by query_start limit 10; 
+1

あなたがトランザクションでアイドル状態のセッションを持っているかどうか聞いてみましょう... –

+0

ここでいくつかのモニタリングを追加する必要があります。 –

+0

テーブルではなくインデックスにロックされていますか?あなたはそのインデックスを再構築することができますが、selectには使用できません。 –

関連する問題