Cache last known per-tuple offsets to speed long tuple accessを実装したときのメモ
カラム数が多いテーブルをjoinするとき,heaptuple.cのnocachegetattr()に負荷がかかる。
390行目付近のfor()ループで,カラムの先頭から調べてるので,カラム数が多いほど負荷が高くなる。
ExecProject() -> ExecTargetList() -> ExecEvalExpr() -> ExecEvalVar() -> nocachegetattr()
TupleTableSlotにheap_deformtupleした結果をキャッシュすることはできないか?
・TupleTableSlotに,heap_deform用のメンバを追加。 追加するメンバは,values, nulls, データが有効かどうかのフラグ。 ・ExecAllocTableSlot(), MakeTupleTableSlot()に新しいメンバを初期化する処理を追加 (初期化処理は共通関数にする) ・ExecClearTuple()で,フラグをクリアする。 ・ExecDropTupleTable()で,values, nullsのメモリを開放する。 ・ExecEvalVar()でカラム数が多い場合は,heap_deformtupleを使う。 検討事項 ・どこでvalues, nullsのメモリを確保するか ・ExecEvalVarでheap_deformtupleを使う条件
include/access/htup.h struct DeformTupleStateの追加 InitDeformTupleStateマクロの追加 CheckDeformTupleExtractedマクロの追加 backend/access/common/heaptuple.c heap_deformtuple_incr()の追加 heap_deformtuple()の変更 include/access/heapam.h heap_deformtuple_incr()の宣言を追加 include/executor/tuptable.h TupleTableSlot構造体を拡張 TupleTableData構造体を拡張 backend/executor/execTuples.c ExecFreeSlotDeformCache()を追加 ExecAllocSlotDeformCache()を追加 ExecSetSlotDescriptor()で,cacheメモリの開放/アロケート処理を追加 ExecDropTupleTable()で,cacheメモリの開放処理を追加 InitTupleTableSlot()を追加(code cleanup) ExecAllocTableSlot()とMakeTupleTableSlot()で,InitTupleTableSlot()を利用する ExecCreateTupleTable()で,MemoryContextを保存 ExecClearTuple()で,DeformTupleStateをリセットする処理を追加 include/executor/executor.h DeformTupleCacheIsValidマクロを追加 backend/executor/execQual.c ExecEvalVar()でdeform_cacheが利用できるときは,heap_deformtuple_range()を使うように変更。
test data --------- 15,000 rows, 200 column data type: text select t100, t110, t120, t130, t140, t150, t160, t170, t180, t190, t200 from aaa original ---------- Each sample counts as 0.01 seconds. % cumulative self self total time seconds seconds calls s/call s/call name 70.05 1.31 1.31 163846 0.00 0.00 nocachegetattr 8.02 1.46 0.15 163840 0.00 0.00 FunctionCall3 1.87 1.50 0.04 397763 0.00 0.00 AllocSetFreeIndex 1.60 1.52 0.03 163840 0.00 0.00 ExecEvalVar 1.34 1.55 0.03 200414 0.00 0.00 AllocSetAlloc total time is 1.87 sec. patched ---------- Each sample counts as 0.01 seconds. % cumulative self self total time seconds seconds calls ms/call ms/call name 39.73 0.29 0.29 180224 0.00 0.00 heap_deformtuple_incr 9.59 0.36 0.07 163840 0.00 0.00 FunctionCall3 6.85 0.41 0.05 16384 0.00 0.02 ExecTargetList 5.48 0.45 0.04 23477 0.00 0.00 hash_any 4.11 0.48 0.03 200414 0.00 0.00 AllocSetAlloc total time is 0.73 sec.
最終的にはheap_deformtupleの拡張ではなく、slot_deformtupleという関数が追加された。