PostgreSQL

エグゼキュータ。ビットマップヒープスキャン(Bitmap Heap Scan)

たまに実行計画で見かけるBitmap Heap Scan や Bitmap Index Scan が気になり調べてみた。ここの解説がわかりやすい。 【PostgreSQLウォッチ】第17回 新しい実行プラン・タイプによるPostgreSQL 8.1の性能向上Indexの種類としてビットマップインデックスとい…

エグゼキュータ。LimitとSort

8.3からORDER BYとLIMITの組み合わせが改良されたということで、どう処理されるのか見てみた。参考にしたのは以下のページ。 【特集】期待度大のバージョンアップ - PostgreSQL 8.3の改良点を徹底分析 (11) ORDER BYの高速化 PostgreSQL 8.3 に関する技術情…

EXPLAINでプランツリーの出力

explain verbose select * from hoge; みたいにexplain verboseとすると実行計画と一緒にプランツリーも出力してくれる。そうか、postgresql.confでdebug_print_planを設定しなくてもプランツリーが確認できるのか。ところで、実行計画の見方は公式のドキュ…

エクゼキュータ。集約(Aggregate)

適当なクエリを流して、GROUP BYによる集約がどう実行されるのか見てみた。 DDLとデータ create table person ( name text primary key, country text not null, age integer not null ); insert into person values ('aaa', 'jp', 20), ('bbb', 'us', 30), …

エクゼキュータ。ネストループ結合(Nested Loop Join)

ネストループ結合はExecNestLoop()で実行される。 TupleTableSlot * ExecNestLoop(NestLoopState *node) 気づいたこと書いてみる(順番は関係ない)。 outerとinnerをスキャンして比較項目が合致したらそれをTupleTableSlotとして返す。 返すのは1件だけ。(…

プランツリーのデバッグ出力

http://www.postgresql.jp/document/pg835doc/html/runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHATpostgresql.confのパラメタを変更すればパースツリー、クエリツリー、プランツリーを自動でログ出力できるみたい。そうかわざわざgdbからcall ppr…

エクゼキュータ。PlanStateとExprState

クエリの実行では、プランツリーがそのまま使われるわけではなく、プランツリー(Plan)から変換されたプランステート(PlanState)が使われる。変換を行うのはExecInitNode()。ExecInitNodeのシグネチャは次のとおり。 PlanState * ExecInitNode(Plan *node…

クエリのパース処理。プランツリーの構造体

おとといのプランツリーのデバッグ出力を見ながらデバッグ用の名前と構造体を結び付けてみた。 PLANNEDSTMT PlannedStmt プランツリーを管理する構造体。わかりやすいところでいうとcommandTypeなど、SELECTかUPDATEかなどの区分などをもっている。 NESTLOOP…

クエリのパース処理。クエリツリーの構造体

昨日のクエリツリーのデバッグ出力を見ながらデバッグ用の名前と構造体をとりあえず結び付けてみた。ほとんどがそのままだけど、RTEがRangeTblEntryに対応するのは調べるまでわからなかった。 QUERY Query RTE RangeTblEntry 結合していると結合の結果を表す…

クエリのパース処理

これからしばらくSQLのパースから実行までを見ていこうかなと思う。結合、サブクエリ、集約等がどう処理されるか理解したい。それと集合論的な考え方を身につけたいなぁ。とりあえずはNested Loop Join が行われるSQLで考える。パースツリー、クエリツリー、…

クエリのパース処理。パースツリーの構造体

パースツリーで使われる構造体は parsenodes.h または primnodes.h に定義されている。前回のパースツリーのところで登場したものだと以下のもの。 parsenodes.hに定義された構造体 SelectStmt ResTarget ColumnRef A_Expr A_Const primnodes.hに定義された…

カーソル(ポータル)。フロントエンド/バックエンドプロトコル経由

PostgreSQLでカーソルというと、ドキュメントにあるように次の3つで定義可能らしい。 DECLARE文経由 フロントエンド/バックエンドプロトコルからBindメッセージ経由 サーバプログラミングインタフェース(SPI)経由 カーソルはポータルとも呼ばれる(プログ…

B-Treeインデックス。btbulkdelete()。削除対象のItemを特定するまで

前回のつづき。btbulkdelete()を呼び出す前に、テーブルから削除対象のタプルをスキャンしそのポインタを記憶しておき、後でそれを参照することで削除すべきインデックスのItemを特定していることがわかった。 lazy_scan_heap() VACUUM対象リレーション(イ…

B-Treeインデックス。btbulkdelete()。PageからItemを削除するところ

インデックスの削除のときに呼ばれるbtbulkdelete()を見てみる。削除はSQLのDELETE実行時ではなくVACUUMのときに行われる。概要はインタフェースであるambulkdeleteのところをみるとわかる。インデックスアクセスメソッド関数。GDBでbtしたときの呼び出しシ…

B-Treeインデックス。btinsert()。ページの分割が必要な場合

前回の続き。_bt_insertonpg() から呼び出される次の3つの関数を中心にインデックス追加時のページ分割の処理を見てみた。 _bt_findsplitloc() : どのタプル以降を新しく作成する右側のページに移動するかを決める pageがright mostのときはFILLFACTORに応じ…

B-Treeインデックス。btinsert()。ページの分割が不要な場合

インデックスの追加のときに呼ばれるbtinsert()を見てみる。btinsert()はINSERTやUPDATEやCOPYの処理で呼ばれることがある。概要はインタフェースであるaminsertのところをみるとわかる。インデックスアクセスメソッド関数。呼び出しシーケンス(抜粋)はこん…

B-Treeインデックス。btbuild()。インデックスのページを書き出すまで

インデックスの構築のときに呼ばれるbtbuild()について前回のつづき。_bt_leafbuild()から。 _bt_leafbuild() BTWriteStateを作成する。BTWriteStateはどれだけページを割り当てたかとか何番目のページまで書き込んだかを管理する。 tuplesort_performsort()…

B-Treeインデックス。btbuild()。インデックスのタプルを一時領域に格納するまで

インデックスの構築のときに呼ばれるbtbuild()を見てみる。btbuild()はCREATE INDEXとかインデックスの再構築で呼ばれる。概要はインタフェースであるambuildのところをみるとわかる。インデックスアクセスメソッド関数。今回は、CREATE INDEXしたときを確か…

B-Treeインデックス。btbeginscan()

インデックスアクセスメソッドのインタフェース定義というものがあり、インデックスの実装を抽象化している。「select * from pg_am」とすれば、インデックスの種類ごとのインタフェースを実装した関数の名前がわかる。 B-Treeインデックスの場合、次のもの…

JDBCドライバ。更新件数の取得

Statement#executeUpdate()やStatement#getUpdateCount()でINSERTやUPDATEやDELETEの更新件数がバックエンドでどうつくられフロントエンドに渡ってくるかみてみた。 バックエンド バックエンドは、フロントエンドからのクエリ実行要求を受け付けるexec_execu…

B-Treeインデックス。btgettuple()。検索時に使われる関数のざっくりとした概要

backend/access/nbtree/READMEを読んでもよくわからなかったので先にコードを追うことにした。bt_first()の前半部分はとりあえずとばして後半部分を眺めていたら最初よりはずいぶん見通しが良くなってきた。 index_getnext() IndexScanDesc.xs_ctup.t_self …

B-Treeインデックス。内部状態?

この2つの構造体の役割がわからない。コメントによるとインデックススキャンに必要な内部の状態らしい。 BTScanOpaqueData BTScanPosData backend/access/nbtree/READMEを読んで明日もういっかい考える。

B-Treeインデックス。pg_filedumpと検索時の呼び出しシーケンスの確認

これまでにタプルの追加と削除を軽く見たので、今度はタプルの更新を見てみようと思った。だけど、Heap Only Tuple(HOT)の関係でタプルの更新処理にはインデックスに関するものも出てくる。ということで、先にインデックスを見ることにした(単にインデッ…

バッファ管理。タプルの削除

DELETEを実行するとだいたいこんな流れ。 条件に合ったタプルを持ってくる。持ってくるときの処理はバッファ管理。バッファの読み書きと同じ。(リンク先も今回もシーケンススキャンされることを前提。) HeapTupleSatisfiesUpdate()を呼んでタプルが更新可…

バッファ管理。タプルのロックの開放

トランザクションが終了すれば実質のロックは開放されるが、ページ上のタプルに対しロック時にオンにされたビットフラグはトランザクションのコミットやロールバックではオフにされない。 ロックが必要な処理(heap_lock_tuple(), heap_update(), heap_delet…

PostgreSQLのコードを読むときに参考にしたいチューニングポイント

チューニングポイントに焦点をあてて(なぜ速くなるのかを考えて)コードを読むとおもしろそう。 参考にさせてもらいます。 PostgreSQLを高速化する16のポイント PostgreSQL パフォーマンスチューニングまとめ わかるPostgreSQLの設定とチューニング

バッファ管理。タプルの追加時のFKチェック

【PostgreSQLウォッチ】第20回 PostgreSQL 8.1ベータ・テスト開始,新機能ロールと共有行ロックを参考にFKのチェックが行われる流れを確認した。まず準備としてリンク先と同じように次のようなSQLをpsqlで実行。 CREATE TABLE t1(i INTEGER PRIMARY KEY, j I…

バッファ管理。チェックポイント。トランザクションが未確定のデータのフラッシュについて

昨日の宿題への回答。 CHECKPOINTの処理でトランザクションが未確定の変更がフラッシュされるのか? 答え される。タプルを追加し、まだトランザクションをコミットもロールバックもしていない時に、CHECKPOINTを実行して確かめた。フラッシュされたかどうか…

CLOG

CLOGのフォーマット CLOGではトランザクションごとのコミット状態のデータを持つ。ひとつのトランザクションにつき2ビットしか使わない。要するに状態は4種類だけということ。とりうる状態は次のように定義されている。 #define TRANSACTION_STATUS_IN_PROGR…

バッファ管理。チェックポイント

チェックポイントでLSNを参照するか? バッファ管理。タプルの追加。宿題への回答でLSNを調べたときに、LSNがチェックポイントのときにも参照されるかどうか未確認と書いたけど、参照されていた。 チェックポイントで、ダーティーなページをフラッシュする前…