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 > > >