none
SQLServer2000と2005の非互換問題(絞り込み処理と計算処理の実行順序) RRS feed

  • 質問

  • こんにちは。

    SQLServer2000から2012への移行を行なうことになりました。

    で、まず、2000と2005の間の非互換箇所を調査しているのですが、以下のような非互換が記載してありました。

    「クエリ式に関するエラーと警告のトラブルシューティング」

    http://msdn.microsoft.com/ja-jp/library/ms188295(v=sql.90).aspx

    -----抜粋↓------------------------------

    重要:

    検索条件、選択リスト、またはクエリ内のそれ以外の部分に使用される式は、分解されて 1 つ以上の独立した式に再構成される場合があります。このように独立した式は、SQL Server によってどのような順序で評価されるか特定できません。結合を含め、フィルタ操作は、必ずしも結果列が計算される前に適用されるわけではありません。

    -----抜粋↑------------------------------

    詳細は上記のページを参照していただきたいのですが、記載によると、例えば今まで(2000以前)は絶対にエラーが起きることのなかった

    --※テーブルtにint型の列a, bがあり、b=0なレコードも含まれている想定
    select a / b
     from t
     where b <> 0
    

    のようなSQLが、2005では場合によってはwhere句でのレコード絞り込みより先にselect句の計算が実施されて[0除算エラー]が発生しうる、と理解したのですがこの理解で正しいのでしょうか?
    (※上記ページには[HASH JOIN]というある意味レアなオプションを使用した再現例が記載されていますが、そのようなオプションに限った話ではなく、where句による基本的な絞り込みでさえも、それより先に計算処理が実行される可能性がある、と理解しました)

    これがエラーになりうるならば、あまりにも既存PGMへの影響が広大(PGMからすべてのSQL算術演算箇所をピックアップして修正要否の調査→必要であれば修正、をしないといけない)なので、ホントに自分の理解で合っているのか不安に感じている次第です。

    ご存知の方、ご回答をよろしくお願いします。

    2014年7月10日 8:01

回答

  • ご理解のとおりです。

    SQL は処理順序を定義する言語ではありませんので、処理順序を仮定した開発で工数を省いていたのであれば、その分検証時に工数が掛かるのも致し方ないかと思います。
    ただ、勘定系や医療関連でなければ目指す稼働率があると思われますので、それにあわせた品質とコストのバランスを取るべきかと思います。
    たとえば、実際に繁忙期や月次の締めなどのトランザクションを再現して動作すれば良しとするですとか、問題のあるクエリは実行プランを固定してしまうですとか、是非や良し悪しはさておき何らかの手法が考えられるかと思います。
    #誤動作が許されない勘定系などで起きているのでしたら・・・ご愁傷様です、開発時の品質責任者を恨みましょう・・・。

    あと、ご提示のクエリであれば、b 列に統計情報が作られるはずですし、Index も張るかと思いますので、エラーになることはほぼ無いですね。
    オプティマイザの詳細な動作は非公開かつ SP などで調整が入るので絶対ではありませんが、割り算と選択の組み合わせであれば、選択を先に行うほうが通常は速くなりますので、割り算を先に行う実行プランを選択する理由がありません。

    ただし、たとえば a/b を計算列として定義している場合はエラーになる可能性があるので、その点は検証されるべきかと思いますので、念のため付記しておきます。


    MCITP(Database Developer/Database Administrator)

    • 回答の候補に設定 星 睦美 2014年7月14日 1:41
    • 回答としてマーク mimura 2014年7月15日 5:01
    2014年7月13日 8:18
  • 解決済みとなっていますが。

    オプティマイザによりどのような判断が下されるか不明なため問題になりそうではありますが、各クエリにはUSE PLANクエリヒントを使用することで具体的なXMLプランを指定することができます。演算順序も指定することでこの問題を回避することはできると思います。

    • 回答としてマーク mimura 2014年7月16日 1:10
    2014年7月16日 0:46

すべての返信

  • ご理解のとおりです。

    SQL は処理順序を定義する言語ではありませんので、処理順序を仮定した開発で工数を省いていたのであれば、その分検証時に工数が掛かるのも致し方ないかと思います。
    ただ、勘定系や医療関連でなければ目指す稼働率があると思われますので、それにあわせた品質とコストのバランスを取るべきかと思います。
    たとえば、実際に繁忙期や月次の締めなどのトランザクションを再現して動作すれば良しとするですとか、問題のあるクエリは実行プランを固定してしまうですとか、是非や良し悪しはさておき何らかの手法が考えられるかと思います。
    #誤動作が許されない勘定系などで起きているのでしたら・・・ご愁傷様です、開発時の品質責任者を恨みましょう・・・。

    あと、ご提示のクエリであれば、b 列に統計情報が作られるはずですし、Index も張るかと思いますので、エラーになることはほぼ無いですね。
    オプティマイザの詳細な動作は非公開かつ SP などで調整が入るので絶対ではありませんが、割り算と選択の組み合わせであれば、選択を先に行うほうが通常は速くなりますので、割り算を先に行う実行プランを選択する理由がありません。

    ただし、たとえば a/b を計算列として定義している場合はエラーになる可能性があるので、その点は検証されるべきかと思いますので、念のため付記しておきます。


    MCITP(Database Developer/Database Administrator)

    • 回答の候補に設定 星 睦美 2014年7月14日 1:41
    • 回答としてマーク mimura 2014年7月15日 5:01
    2014年7月13日 8:18
  • ご回答いただき、ありがとうございます。

    やはり、エラーになる「可能性はある」のですよね。

    いろいろ丁寧に説明いただき参考になりました。 ありがとうございました。

    2014年7月15日 5:22
  • 解決済みとなっていますが。

    オプティマイザによりどのような判断が下されるか不明なため問題になりそうではありますが、各クエリにはUSE PLANクエリヒントを使用することで具体的なXMLプランを指定することができます。演算順序も指定することでこの問題を回避することはできると思います。

    • 回答としてマーク mimura 2014年7月16日 1:10
    2014年7月16日 0:46