web-dev-qa-db-ja.com

postgresは、オペレーション間に大きなギャップがある計画を説明します

結合、並べ替え、フィルター処理の間に大きなギャップがあるようで、説明できない(申し訳ありません)postgresqlの説明プランがあります。クエリに非常に時間がかかり、計画されたバージョンは実際のバージョンとは大きく異なります。このセッションでwork_memを1500MBに上げようとしましたが、それでもディスクにスワップしています(これは、2つの巨大な(1GB)ソートがあるためです)?

explain analyze SELECT DISTINCT ac.player_id, gvt.game_type,
 first_value(platform) over (partition by acs.start_ts, acs.account_id
 order by start_ts desc rows between unbounded preceding and unbounded following) platform,
 date_trunc('hour', ac.audit_ts),
 first_value(audit_ts) over
   (partition by platform, game_type, acs.account_id
  order by audit_ts desc rows between unbounded preceding and unbounded following)
 FROM audit_command ac
 JOIN table_definition td ON ac.table_id = td.table_id
 JOIN game_variation_template gvt ON td.game_variation_template_id = gvt.game_variation_template_id
 LEFT JOIN player_definition p ON ac.player_id = p.player_id
 LEFT JOIN account_session acs ON p.account_id = acs.account_id
 WHERE ac.command_type::text <> 'Leave'::text AND ac.command_type::text <> 'GetStatus'::text
 and start_ts < audit_ts and start_ts >= audit_ts - interval '1 day'
 AND ac.audit_ts between '2014-06-26T02:10:01.017+01:00' AND '2014-06-27T02:10:01.017+01:00'
;
クエリプラン
 -------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- ------------------------------- 
 HashAggregate(コスト= 4781863.47..4824152.70行= 3383139幅= 47 )(実際の時間= 1783393.417..1783412.946行= 34251ループ= 1)
-> WindowAgg(コスト= 4646537.91..4739574.23行= 3383139幅= 47)(実際の時間= 1735317.999..1772580.060行= 14568155ループ= 1)
->並べ替え(コスト= 4646537.91..4654995.75行= 3383139幅= 47)(実際の時間= 1735317.969..1756145.084行= 14568155ループ= 1)
並べ替えキー:acs。プラットフォーム、gvt.game_type、acs.account_id、ac.audit_ts 
並べ替え方法:外部マージディスク:1108544kB 
-> WindowAgg(コスト= 4211974.87..4279637.65行= 3383139幅= 47)(実際時間= 1125155.357..1140058.023行= 14568155ループ= 1)
->並べ替え(コスト= 4211974.87。 .4220432.72行= 3383139幅= 47)(実際の時間= 1125141.693..1128195.716行= 14568155ループ= 1)
並べ替えキー:acs.start_ts、acs.account_id 
並べ替え方法:外部並べ替えディスク:975392kB 
->ハッシュ結合(コスト= 1274416.28..3845074.61行= 3383139幅= 47)(実際の時間= 1034359.154..1098242.110行= 14568155ループ= 1)
ハッシュ条件:(td .game_variation_template_id = gvt.game_variation_template_id)
->ハッシュ結合(コスト= 1274374.79..3798514.96行= 3383139幅= 42)(実際の時間= 1034359.024..1091131.468行= 14568155ループ= 1)
ハッシュ条件:(ac.table_id = td.table_id)
->ハッシュ結合(コスト= 1217034.45..3665053.99行= 3383139幅= 46)(実際の時間= 1033746.587..1082753.263行= 14568157ループ= 1) 
ハッシュ条件:(acs.account_id = Lobby_user.account_id)
参加フィルター:((acs.start_ts <ac.audit_ts)AND(acs.start_ts> =(ac.audit_ts-'1日'::間隔)))[。__ __。]結合フィルターによって削除された行:1953618923 
-> account_session acsでのシーケンススキャン(コスト= 0.00..1507571.65行= 46583265幅= 22)(実際の時間= 0.004..56952.205行= 43264444ループ= 1 )
->ハッシュ(コスト= 1150844.59..1150844.59行= 5295189幅= 31)(実際の時間= 15666.924..15666.924行= 3835505ループ= 1)
バケット:1048576バッチ:1メモリ使用法:253959kB 
->ハッシュ結合(コスト= 691441.16..1150844.59行= 5295189幅= 31)(実際の時間= 7817.384..13276.084行= 3835524ループ= 1)
ハッシュ条件:( ac.player_id = Lobby_user.player_id)
-> audit_command acでaudit_command_ts_idxを使用したインデックススキャン(コスト= 0.57..340262.25行= 5295189幅= 24)(実際の時間= 0.025..2697.823行= 3835524ループ= 1 )
インデックス条件:((audit_ts> = '2014-06-26 02:10:01.017' :: timestamp without time zone)AND(audit_ts <= '2014-06-27 02:10:01.017' :: timestタイムゾーンのないアンプ))
フィルター:(((command_type):: text <> 'Leave' :: text)AND((command_type):: text <> 'GetStatus' :: text))
フィルターによって削除された行:16517 
->ハッシュ(コスト= 590189.15..590189.15行= 8100115幅= 14)(実際の時間= 7813.606..7813.606行= 8300768ループ= 1)
バケット:1048576バッチ:1メモリ使用量:377469kB 
-> lobby_userでのシーケンススキャン(コスト= 0.00..590189.15行= 8100115幅= 14)(実際の時間= 0.020..3667.951行= 8300768ループ= 1 )
->ハッシュ(コスト= 32174.04..32174.04行= 2013304幅= 12)(実際の時間= 611.500..611.500行= 1952805ループ= 1)
バケット:262144バッチ:1メモリ使用法:84599kB 
-> table_definition tdでのシーケンススキャン(コスト= 0.00..32174.04行= 2013304幅= 12)(実際の時間= 0.007..198.591行= 1952805ループ= 1)
- >ハッシュ(コスト= 39.55..39.55行= 155幅= 1 5)(実際の時間= 0.116..0.116行= 155ループ= 1)
バケット:1024バッチ:1メモリ使用量:8kB 
-> game_variation_template gvtでのシーケンススキャン(コスト= 0.00。。 39.55行= 155幅= 15)(実際の時間= 0.009..0.067行= 155ループ= 1)

バキュームされていないaudit_commandテーブルだと感じましたが、週末に自動バキュームが実行され、テーブルが開始されました。

analyze verbose audit_command;
INFO:  analyzing "public.audit_command"
INFO:  "audit_command": scanned 30000 of 15429435 pages, containing 861531 live rows and 39590 dead rows; 30000 rows in sample, 586507527 estimated total rows

誰かが問題が何であるか、そしてなぜ実行がとても遅いのか(以前の2倍)を教えてもらえますか?

1
JaeRae

何が「ギャップ」を引き起こしているのか正確にはわかりませんが、パフォーマンスの最大のボトルネックは次のとおりです。

参加フィルター:((acs.start_ts <ac.audit_ts)AND(acs.start_ts> =(ac.audit_ts-'1 day ':: interval)))

につながる:

結合フィルターによって削除された行:1953618923

20億を超える行を繰り返すには、しばらく時間がかかります。その特定の結合は、以下に基づいてすべてを結合しているため、クエリを強制終了します。

ハッシュ条件:(acs.account_id = Lobby_user.account_id)

日付範囲に関係なく、結合フィルターで日付範囲外のすべてを除外します。

過去のある時点で高速だったとおっしゃっていたので、まだチェックしていない場合は、 肥大化したインデックス をチェックする価値があるかもしれません。ただし、これは主に、account_session内のデータ量が増え続けることの副作用であると思われます。

また、「個別」が1,400万行を35K行に減らしているという事実から、必要な情報を取得するためのより良い方法があるのではないかと思います(ウィンドウ関数のいずれかを、集計関数を使用したgroupbyで置き換えることができます) ?)。

2
user44784