結果に影響しない結合ならInnerJoinに?デフォルトは...

閲覧: 128 回
最初の未読メッセージにスキップ

jflute

未読、
2011/07/26 4:19:062011/07/26
To: DBFluteユーザの集い
jfluteです。

ページングでカウント検索を先に後に?デフォルト
https://groups.google.com/group/dbflute/browse_thread/thread/a7bc5d33f8b88ea8?hl=ja

ページングでカウント検索の結合を最小限に?デフォルトは...
https://groups.google.com/group/dbflute/browse_thread/thread/a05808a0e2f02f52?hl=ja

に続いて、これまた似たような別のお話。

ConditionBeanの結合は left outer join が基本ですが、
ほとんどの場合においてそれで問題ないものではありますが、
稀に InnerJoin にしないと早くならないケースがあります。

自分が知っている現象としては二つ、

o PostgreSQL で結合先テーブルのカラムで絞り込み条件したとき
o Sybase で結合先テーブルのカラムで絞り込み条件したとき

しかも、

o その絞り込み条件でバインド変数を止めてリテラル値にすると速い
o InnerJoin にすると速い

それを想定して、もともとDBFluteではピンポイントで
InnerJoin にする機能があります。

// (Manual)InnerJoin
http://dbflute.sandbox.seasar.org/ja/manual/function/ormapper/conditionbean/query/manualinnerjoin.html

本来、オプティマイザでどうにかしてもらいたいなと思うところですが、
そうならないDBもあるし、ケースによってはどのDBでもあるかもしれないし。
ということで、0.9.8.8 からは、自動判別してInnerJoinにする機能が入りました。

// InnerJoinAutoDetect
http://dbflute.sandbox.seasar.org/ja/manual/function/ormapper/conditionbean/sidebar/innerjoinautodetect.html

ロジックとしては、

o where句の絞り込み条件として利用された結合ならInnerJoin
-> IsNull は除く (結合先が存在しないレコードを示すため)
-> OrScopeQuery は除く (絞り込みとして確定しないため)
-> InlineViewやOrClauseの絞り込み条件も(当然)除く
o InnerJoinと判断された結合の経路となる結合もInnerJoinになる
-> SQLの文法的にはそれで検索結果が変わることはないため
o FKカラムのNotNull制約は判断要素にはしない
-> 厳密さが難しいのと、主なチューニング対象は
結合先テーブルのカラムで絞り込み条件したときと考えるため

という感じです。
考える限り考えたんですけど、何かあればコメントください。
既に dbflute-mysql-example ではこれがデフォルトになっていて、
単体テストは全てグリーンになっています。
現在進行形でもっと厳密なテストもやっています。

FKカラムのNotNull制約による判断は、ちょっと迷いどころです。
本物のFK制約(Additionalじゃない)、かつ、NotNull制約、
かつ、InlineViewやOnClauseの条件がない結合に関しては、
論理的にはInnerJoinでいいはずですが、勇気が。。。

こちらもDBFluteのデフォルトにするか検討中です。
ただ、やるなら 0.9.8.8 が安定したかな、というところで、
早めにデフォルトの挙動変更だけのバージョンを出す方が
いいと思うので、そういう流れを考えています。

kubo

未読、
2011/07/27 7:31:442011/07/27
To: DBFluteユーザの集い
jfluteです。

デフォルト化に向けて最終調整を行っています。
既にリリースした 0.9.8.8 ではピンポイントの
チューニングオプションなのである程度の割り切りが
許されますが、デフォルトとなるともっと精密さが
求められます。

> o where句の絞り込み条件として利用された結合ならInnerJoin
>  -> IsNull は除く (結合先が存在しないレコードを示すため)
>  -> OrScopeQuery は除く (絞り込みとして確定しないため)
>  -> InlineViewやOrClauseの絞り込み条件も(当然)除く

ここに関して、さらに

o NotExistsReferrer は除く
o (Query)DerivedReferrerの IsNull、coalesce は除く
o ColumnQuery の coalesce は除く
o ColumnQuery の (Specify)DerivedReferrer は(問答無用で)除く

を判別ロジックに追加しました。
(もうじっくり考えないとわけわからないと思いますが...一応オープンに)

要は、対象カラムが Null のデータをヒットさせることが
できるかどうか、ヒットする可能性が1%でもあるかどうか、
というところです。テストをさらに増やしている最中です。
(coalesce が超厄介だった...null が正常な値に生き返るわけなので)

> o FKカラムのNotNull制約は判断要素にはしない
>  -> 厳密さが難しいのと、主なチューニング対象は
>   結合先テーブルのカラムで絞り込み条件したときと考えるため

こっちはできるようにはしましたが、自動判別とは独立した
仕組みにして、オプションにするかデフォルトにするかは
自動判別とは別に設定できるようにしています。
DBFluteとしては、NotNull 制約を見て何か挙動を変えるというのは
今まで一切やってない(はずな)ので、NotNull 制約に依存する処理を
デフォルトにするのはちょっと抵抗があります。(要検討)

2011/7/26 jflute <dbf...@gmail.com>:

> --
> このメールは Google グループのグループ「DBFluteユーザの集い」の登録者に送られています。
> このグループに投稿するには、dbf...@googlegroups.com にメールを送信してください。
> このグループから退会するには、dbflute+u...@googlegroups.com にメールを送信してください。
> 詳細については、http://groups.google.com/group/dbflute?hl=ja からこのグループにアクセスしてください。
>
>

kubo

未読、
2011/07/29 12:50:562011/07/29
To: DBFluteユーザの集い
jfluteです。

ひとまず、次のバージョンではこの機能はデフォルトにはせず、
それまで通りオプションとします。
(代わりに、Paging系の他のオプションをデフォルトに)

いずれにせよ、簡易に効率の良い inner join が
利用できるようになりました。
パフォーマンスチューニングで left outer join があやしいと
思ったらとりあえず allowInnerJoinAutoDetect() を呼んでみると
良いと思います。

>> o where句の絞り込み条件として利用された結合ならInnerJoin
>>  -> IsNull は除く (結合先が存在しないレコードを示すため)
>>  -> OrScopeQuery は除く (絞り込みとして確定しないため)
>>  -> InlineViewやOrClauseの絞り込み条件も(当然)除く

CBで IsNullOrEmpty という演算子を追加したので、
それも除外条件に含めました。(テスト済み)

> こっちはできるようにはしましたが、自動判別とは独立した
> 仕組みにして、オプションにするかデフォルトにするかは
> 自動判別とは別に設定できるようにしています。
> DBFluteとしては、NotNull 制約を見て何か挙動を変えるというのは
> 今まで一切やってない(はずな)ので、NotNull 制約に依存する処理を
> デフォルトにするのはちょっと抵抗があります。(要検討)

こちら対応しました。テストもしっかりと行い確度を上げたので、
自動判別と同じオプションに組み込みました。
ただ、FixedCondition の OverRelation が存在する場合は、
結合条件の中でどのように結合同士が関連しているかを
トレースするのが難しいので抑制されるようにしています。
(OverRelationなんて知ってる人ほとんどいないでしょうけど...)

http://dbflute.sandbox.seasar.org/ja/manual/function/genbafit/implfit/bizonetoone/index.html#over

2011/7/27 kubo <dbf...@gmail.com>:

jflute

未読、
2011/08/19 23:32:352011/08/19
To: DBFluteユーザの集い
jfluteです。

この件、一旦寝かしています。
他のPaging系のデフォルト化からもう少し時間置いて、
さらに再検討します。
> http://dbflute.sandbox.seasar.org/ja/manual/function/genbafit/implfit...
>
> 2011/7/27 kubo <dbfl...@gmail.com>:
> > 2011/7/26 jflute <dbfl...@gmail.com>:
> >> jfluteです。
>
> >> ページングでカウント検索を先に後に?デフォルト
> >>https://groups.google.com/group/dbflute/browse_thread/thread/a7bc5d33...
>
> >> ページングでカウント検索の結合を最小限に?デフォルトは...
> >>https://groups.google.com/group/dbflute/browse_thread/thread/a05808a0...
>
> >> に続いて、これまた似たような別のお話。
>
> >> ConditionBeanの結合は left outer join が基本ですが、
> >> ほとんどの場合においてそれで問題ないものではありますが、
> >> 稀に InnerJoin にしないと早くならないケースがあります。
>
> >> 自分が知っている現象としては二つ、
>
> >> o PostgreSQL で結合先テーブルのカラムで絞り込み条件したとき
> >> o Sybase で結合先テーブルのカラムで絞り込み条件したとき
>
> >> しかも、
>
> >> o その絞り込み条件でバインド変数を止めてリテラル値にすると速い
> >> o InnerJoin にすると速い
>
> >> それを想定して、もともとDBFluteではピンポイントで
> >> InnerJoin にする機能があります。
>
> >> // (Manual)InnerJoin
> >>http://dbflute.sandbox.seasar.org/ja/manual/function/ormapper/conditi...
>
> >> 本来、オプティマイザでどうにかしてもらいたいなと思うところですが、
> >> そうならないDBもあるし、ケースによってはどのDBでもあるかもしれないし。
> >> ということで、0.9.8.8 からは、自動判別してInnerJoinにする機能が入りました。
>
> >> // InnerJoinAutoDetect
> >>http://dbflute.sandbox.seasar.org/ja/manual/function/ormapper/conditi...
全員に返信
投稿者に返信
転送
新着メール 0 件