PostgreSQLの最近のブログ記事

大量データのDELETE/INSERTを処理するバッチ処理をPHPで走らせていたのですが、回数をこなす毎にDBのパフォーマンスが目に見えて落ちてきたため、処理の最後にvacuumを実行することに。

PHPからvacuumをキックする単純な処理なはずが、これがうまく動かない。
PostgreSQL関数経由ではvacuumは実行できないのかとか、いろいろと悩んでいたところ、ようやくあるエラーログに気が付きました。

WARNING: skipping "tablename" --- only table or database owner can vacuum it

要は実行ユーザの権限の問題でした。
wwwユーザにDBの権限を付与したものを使用していたのですが、vacuumを実行できるユーザーは、
・スーパーユーザー
・DBまたはテーブルのオーナー
に限られるいうことのようです。

MAX、MINを抽出するクエリはインデックスを利用しないため高速な処理ができないとのこと。
そのため、クエリをLIMITに置き換えることで高速化を図ろうというテクニックがあるようです。

例えば、以下の構成でクエリを試してみました。

・PostgreSQL7.4.3
・テーブル
CREATE TABLE hogehoge
(
id int4,
id2 int4,
id3 int4,
text1 text,
text2 text,
text3 text,
text4 text,
char1 varchar(2),
date1 date
)
インデックス:hogehoge-id(id)
・レコード数:約4万件


EXPLAIN ANALYZE で問い合わせプランを比較してみます。

EXPLAIN ANALYZE SELECT MAX(id) FROM hogehoge;
------------------------------------------------
Aggregate (cost=1213.13..1213.13 rows=1 width=4) (actual time=356.575..356.577 rows=1 loops=1)
-> Seq Scan on hogehoge (cost=0.00..1115.30 rows=39130 width=4) (actual time=0.024..202.504 rows=39130 loops=1)
Total runtime: 358.997 ms

SELECT id FROM hogehoge ORDER BY id DESC LIMIT 1;
------------------------------------------------
Limit (cost=0.00..0.07 rows=1 width=4) (actual time=1.154..1.156 rows=1 loops=1)
-> Index Scan Backward using "hogehoge-id" on hogehoge (cost=0.00..2550.87 rows=39130 width=4) (actual time=1.138..1.138 rows=1 loops=1)
Total runtime: 1.819 ms

おぉ、違いは歴然です。
あらためてインデックスの効果を実感ですね。

※なお、PostgreSQL8.1からMAX、MINでもインデックスを使って高速処理されるよう改良されたそうです。お気を付け下さい。(私はまだ7の環境をメンテすることが多いので・・・。)

このアーカイブについて

このページには、過去に書かれたブログ記事のうちPostgreSQLカテゴリに属しているものが含まれています。

前のカテゴリはPHPです。

次のカテゴリはSEOです。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

PostgreSQL: 月別アーカイブ

RSSフィード

  • 購読する

いろいろ

あわせて読みたい

フィードメーター - ポップフライ

seo

Powered by Movable Type 4.01