[Ludia-users 85] Re: インデックスコスト推定関数について

Zurück zum Archiv-Index

H.Harada umi.t****@gmail*****
2007年 9月 12日 (水) 16:29:59 JST


こんにちは。

> そのため、プランナに「強引に」インデックススキャンを選択させるために、
> >   *indexTotalCost += -DEFAULT_RANDOM_PAGE_COST;
> のような記述をしています。

個人的な思い込みで申し訳ないのですが、
RANDOM_PAGE_COSTは引き算というより掛け算するものかと思っていたので。

SQL(擬似)は以下のような感じです。
それぞれ15万件ほどのレコードが存在します。

EXPLAIN
SELECT
	COUNT(*),
	COUNT(m_productCode)
FROM
	_search_product
INNER JOIN(
	SELECT productIndex
	FROM _search_text
	WHERE productText @@ 'ポケット'
)keyword USING(productIndex)
CROSS JOIN(
	SELECT null::int4 AS m_productCode
)m_product

で、プラン(最悪)は:

"Aggregate  (cost=-309589.39..-309589.37 rows=1 width=222)"
"  ->  Nested Loop  (cost=-309596.08..-309593.26 rows=140 width=222)"
"        ->  Result  (cost=0.00..0.01 rows=1 width=0)"
"        ->  Materialize  (cost=-309596.08..-309594.68 rows=140 width=218)"
"              ->  Nested Loop  (cost=0.00..-309596.22 rows=140 width=218)"
"                    Join Filter: (_search_product.productindex =
_search_text.productindex)"
"                    ->  Seq Scan on _search_product
(cost=0.00..4501.79 rows=140379 width=218)"
"                    ->  Index Scan using ludia_index on _search_text
(cost=0.00..-3.99 rows=140 width=4)"
"                          Index Cond: ((producttext)::text @@ 'ポケット'::text)"

パッチ適用後:

"Aggregate  (cost=1074.98..1075.00 rows=1 width=222)"
"  ->  Nested Loop  (cost=0.00..1071.10 rows=140 width=222)"
"        ->  Result  (cost=0.00..0.01 rows=1 width=0)"
"        ->  Nested Loop  (cost=0.00..1069.68 rows=140 width=218)"
"              ->  Index Scan using ludia_index on _search_text
(cost=0.00..4.31 rows=140 width=4)"
"                    Index Cond: ((producttext)::text @@ 'ポケット'::text)"
"              ->  Index Scan using _search_product_pkey on
_search_product  (cost=0.00..7.60 rows=1 width=218)"
"                    Index Cond: (_search_product.productindex =
_search_text.productindex)"

最悪時はLudiaIndexのスキャン結果のシークスキャンがN回となっているのに対し、
適用後はLudiaIndex一回のスキャンでJOINにはPrimaryKeyのスキャンが使われています。

> しかし、このような記述をした場合は、EXPLAINでシーケンシャルスキャンが
> 使われているかチェックしてください。
上記のようなプランですが、Ludiaのシークスキャンが使われているのでしょうか??

Hitoshi Harada
umi.t****@gmail*****


07/09/12 に kousa****@nttda*****<kousa****@nttda*****> さんは書きました:
> 幸坂です。こんにちは。
>
> 現在のLudiaはインデックススキャンとシーケンシャルスキャンの
> 二種類を実装しています。
> しかし、シーケンシャルスキャンはインデックススキャンと比較して、
> まだ機能が不十分です。
> そのため、プランナに「強引に」インデックススキャンを選択させるために、
> >   *indexTotalCost += -DEFAULT_RANDOM_PAGE_COST;
> のような記述をしています。
> この記述がないと、シーケンシャルスキャンが使われる事象が増えます。
> 困ります。
>
> ほとんどのクエリでは、上記の記述により強引にインデックススキャンを
> 選択させるべきですが、Haradaさんのような事象では、
> > +   *indexTotalCost = 0.3;
> のような記述もありだと思います。
> しかし、このような記述をした場合は、EXPLAINでシーケンシャルスキャンが
> 使われているかチェックしてください。
>
> シーケンシャルスキャンの機能はLudia1.0と1.2で追加してきました。
> あと少しでインデックススキャンと変わらない機能となる予定です。
> その際に、コストを正確な物にする予定です。
>
> 参考までに、どのようなクエリを発行したのか教えて頂けないでしょうか?
>
> > -----Original Message-----
> > From: ludia****@lists*****
> > [mailto:ludia****@lists*****] On Behalf
> > Of H.Harada
> > Sent: Wednesday, September 12, 2007 10:29 AM
> > To: ludia****@lists*****
> > Subject: [Ludia-users 83]インデックスコスト推定関数について
> >
> > Ludia使わせてもらっています。
> >
> > このほどPostgreSQLを8.1→8.2にバージョンアップしたので
> > Ludiaも0.8→1.2にバージョンアップしたのですが、
> > 一部のクエリが異様に遅くなりました。
> >
> > 原因をつきとめたところ、
> > Ludiaが負の値のインデックスコストを算出してくれた模様。
> > これが比較的深いNestLoopでつかわれていたため、
> > 外側のクエリで(負の値 × 外のコスト)というモラルハザードな計算をもたら
> し、
> > 結果としてPostgreSQLがもっとも「早い」と勘違いした、もっとも遅いプランが選
> 択されていたのでした。
> >
> > ソース的にはludia-1.2.0/pgsenna.cの929行目あたり、
> > #if defined(POSTGRES82) || defined(POSTGRES83)
> >   *indexTotalCost += -DEFAULT_RANDOM_PAGE_COST;
> > #endif
> > の部分ですが、なぜDEFAULT_RANDOME_PAGE_COSTを「引く」必要があるのでしょう
> か。
> >
> >
> > 取り急ぎ該当作業ではindexTotalCostに定数0.3を返すように書き換えたところ、
> > 期待通りに動くようにはなったのですが(下記参照)。。。
> >
> > ちなみに環境は、
> > Windows XP SP2
> > PostgreSQ-L8.2.4
> > Ludia-1.2.0
> > Senna-1.0.8
> > Senna built on VC++2005
> > Mingw gcc 3.4.2
> >
> >
> > *** pgsenna2.c.org    Wed Aug 08 23:28:41 2007
> > --- pgsenna2.c        Wed Sep 12 10:25:38 2007
> > ***************
> > *** 929,934 ****
> > --- 929,936 ----
> >     *indexTotalCost += -DEFAULT_RANDOM_PAGE_COST;
> >   #endif
> >     *indexCorrelation = 1.0;
> > +
> > +   *indexTotalCost = 0.3;
> >     elog(DEBUG1, "pgsenna2: cost=(%f,%f,%f)",
> >          *indexStartupCost, *indexTotalCost, *indexSelectivity);
> >     PG_RETURN_VOID();
> >
> >
> > Hitoshi Harada
> > umi.t****@gmail*****
> >
> > _______________________________________________
> > Ludia-users mailing list
> > Ludia****@lists*****
> > http://lists.sourceforge.jp/mailman/listinfo/ludia-users
> >
>




Ludia-users メーリングリストの案内
Zurück zum Archiv-Index