1

私は現在、より大きなwikipedia-dumpから派生したPostgreSQLデータベースを使用しています。約40GBのデータが含まれています。データベースは、Suse Linux EnterpriseServer10を搭載したHPProliantML370G5サーバーで実行されています。単純なD-Linkルーターによって管理されているプラ​​イベートネットワークを介してラップトップからクエリを実行しています。ラップトップとサーバーの両方に静的DHCP(プライベート)IPを割り当てました。

とにかく、私のラップトップから、pgAdmin IIIを使用して、いくつかのSQLコマンド/クエリを送信します。これらのいくつかは、CREATE INDEX、DROP INDEX、DELETE、SELECTなどです。コマンド(CREATE INDEXなど)を送信すると、クエリが完全に実行されたことなどを通知するコマンドが返されます。ただし、このようなコマンドに割り当てられたポストマスタープロセスはコマンドはサーバー上でスリープ状態のままになっているようです。さて、私はこれを本当に気にしません。PostgreSQLはクエリを処理する準備ができているポストマスターのプールを維持していると自分自身に言います。それでも、このプロセスが9.4GBの割り当てられたRAMのうち6GBを消費する場合、私は心配します(そして今のところそうします)。これは、別のクエリで同じデータを使用する必要が生じた場合に備えて、[共有]メモリに保持されるデータのキャッシュである可能性がありますが、わかりません。

もう一つは私を悩ませています。

私は2つのテーブルを持っています。1つはページテーブルです。page_id列にインデックスがあります。もう1つは、page.page_id列の何も参照しないか変数を参照するpl_from列を持つpagelinksテーブルです。page_id列とは異なり、pl_fromには(まだ)インデックスがありません。テーブルの規模と実行可能な解決策を見つける必要性についてのアイデアを与えるために、ページテーブルには1340万行(不要なものを削除した後)があり、ページリンクテーブルには2億9300万行があります。

次のコマンドを実行して、ページリンクテーブルの役に立たない行を削除する必要があります

DELETE FROM pagelinks USING page WHERE pl_from NOT IN (page_id);

したがって、基本的には、ページテーブルにないページからのすべてのリンクをページリンクテーブルから削除したいと思います。ネストされたループやシーケンシャルスキャンを無効にした後でも、クエリオプティマイザは常に次の「解決策」を提供します。

Nested Loop  (cost=494640.60..112115531252189.59 rows=3953377028232000 width=6)
  Join Filter: ("outer".pl_from <> "inner".page_id)"
  ->  Seq Scan on pagelinks  (cost=0.00..5889791.00 rows=293392800 width=17)
  ->  Materialize  (cost=494640.60..708341.51 rows=13474691 width=11)
        ->  Seq Scan on page  (cost=0.00..402211.91 rows=13474691 width=11)

そのようなタスクは完了するのに数週間以上かかるようです。明らかに、これは受け入れられません。私はむしろそれがそのことをするためにpage_idインデックスを使用することを望んでいるように思えます...しかしそれは頑固なオプティマイザーであり、私は間違っているかもしれません。

4

3 に答える 3

1

実際、クエリの実行を高速化するために一時テーブルを作成することにしました。

CREATE TABLE temp_to_delete AS(
    (SELECT DISTINCT pl_from FROM pagelinks) 
        EXCEPT 
    (SELECT page_id FROM page));
DELETE FROM pagelinks USING temp_to_delete 
    WHERE pagelinks.pl_from IN (temp_to_delete.pl_from);

驚いたことに、このクエリは約 4 時間で完了しましたが、最初のクエリは約 14 時間アクティブなままだったので、それを強制終了することにしました。より具体的には、DELETE は以下を返しました。

Query returned successfully: 31340904 rows affected, 4415166 ms execution time.

私の質問の最初の部分については、postmaster プロセスが確かにキャッシュにいくつかの情報を保持しているようです。別のクエリがキャッシュと一部のメモリ (RAM) にない情報を必要とする場合、キャッシュは空になります。そして、ポストマスターは確かにプロセスのプールにすぎません.

また、gnome-system-monitorは不完全な情報を提供し、情報価値が無価値であるため、神話であるということも思い浮かびました。最近混乱しているのは、主にこのアプリケーションのせいです。たとえば、他のユーザー (postgres ユーザーなど) のメモリ使用量は考慮されておらず、12 GB の RAM が残っているとさえ教えてくれますが、これは真実ではありません。したがって、postgreSQL がそのリソースをどのように使用しているかを知りたいので、いくつかのシステム モニターを試してみました。xosviewは確かに有効なツールのようです。

お役に立てれば!

于 2009-01-06T00:48:45.223 に答える
1

2番目の質問に; CREATE TABLE AS ステートメントを使用して、必要なレコードだけを含む新しいテーブルを作成してみてください。新しいテーブルが十分に小さい場合は、高速になる可能性がありますが、役に立たない場合もあります。

于 2009-01-05T21:14:22.473 に答える
0

クライアントへの接続が開いている限り、ポストマスタープロセスはそこにとどまります。pgadminは接続を閉じますか?知らない。

使用されるメモリは、shared_buffers(構成設定を確認してください)である場合とそうでない場合があります。

さて、クエリ。このような大規模なメンテナンス操作の場合は、work_memを数GBなどの大きなものに自由に設定してください。RAMがたくさんあるように見えるので、それを使用してください。

work_memを「4GB」に設定します。EXPLAIN DELETE FROM pagelinks WHERE pl_from NOT IN(SELECT page_id FROM page);

ページをseqスキャンしてハッシュし、pagelinksをseqスキャンして、ハッシュを調べてpage_idsを確認する必要があります。かなり速いはずですが(4時間よりはるかに速いです!)、ハッシュには大きなwork_memが必要です。

ただし、テーブルのかなりの部分を削除するので、次のように実行する方が速い場合があります。

CREATE TABLE pagelinks2 ASSELECTa。*FROMpagelinks a JOIN pages b ON a.pl_from = b.page_id;

(INの代わりに単純なJOINを使用できます)

このクエリにORDERBYを追加することもできます。そうすれば、後で最適にアクセスできるように、新しいテーブルがディスク上で適切に順序付けられます。

于 2009-10-27T23:25:30.210 に答える