2つのSQLステートメントの数学的等価性


9

2つのSQLステートメントの数学的等価性を確認する方法はありますか?

2つのSQLステートメントがあります。

  • SQL_STATEMENT_1
  • SQL_STATEMENT_2

データに対して両方のステートメントを実行し、出力を比較してもまったく役に立ちません。

方程式ソルバーが行うように、ステートメントの背後にあるセット数学を評価する必要があります。

私の質問の範囲外のものは次のようなものです:

  • 等しいかどうかの比較(より大きい、より小さい、LIKEなど)
  • ストアドプロシージャ、またはトリガー
  • 共通テーブル式(WITH)

スコープ内:

  • 副選択:WHERE other_id IN(SELECT id FROM other WHERE ...)
  • 結合

部分的な解決策は、2つのクエリの実行プランを比較することです。実行計画が同じ場合、それらは等しくなります。ただし、この関係は双方向には機能しません。実行プランが異なる2つの論理的に同等のクエリが存在する可能性があります。
BuahahaXD 2015

1
@BuahahaXD:それは真実ではありません。select * from foo where id = 4最も確かに同じ実行計画を持つことになりますselect * from foo where id = 2
a_horse_with_no_name

@a_horse_with_no_name SQL Serverでテストし、2つの異なるXMLファイルを取得しました。パラメータは、XMLファイルの<ParameterList>ノードとして含まれていました。視覚的には、これらのプランは同じでした(テーブルスキャン+選択)。しかし、実行計画を比較することは正しいと思います。
BuahahaXD 2015

1
一意のキーに関しては、@ a_horse_with_no_nameが正しいです。他のすべての場合、1)インデックス統計が最新でない場合、および2)インデックス統計が最新であっても、idのキー分布が偏っている場合、2つの異なる実行プランを持つ可能性がselect * from foo where id = 4ありselect * from foo where id = 2ます。 (提供されたIDは一意のキーではありません)。
RolandoMySQLDBA 2015

回答:


6

2つのSQLステートメントの数学的な同等性は何ですか?私にとって、2つのクエリは、いずれのデータセットでも同じである場合に、同じ結果セットを返す場合、同等です。

ご指摘のとおり、リレーショナル代数のスーパーセットであるSQLクエリは非常に複雑になる可能性があります。サブクエリを混合し、ストアドプロシージャと関数(確定的どうかに関係なく)を使用して、クエリを実際のコードのように見せることができます。これらの種類のクエリについて話している場合、それは本当に難しいでしょう。実際、「2つのアルゴリズムは同等である」問題とおそらく同じです。

それらの条件下では、おそらくそれは不可能です。

しかしながら...

... 比較する2つのクエリが厳密な集合演算である場合は、実行できる可能あります。その場合は、クエリをリレーショナル代数に変換してから、等価ルールに従って計算できます。自明でないブール条件を使用した選択/制限がある場合、それらの条件も同等であることを証明する必要があるかもしれません。その後、ブール代数に依存する必要があり、おそらく真理値表を作成することになります

ご覧のとおり、これは大変な作業であり、私の知る限り、すべてを自動的に計算する方法はありません。それにもかかわらず、タスクに取り組みたい場合に役立つと思われるツールをいくつか見つけました。


私の質問は、集合演算についてのみです。質問を更新しました。これは「2つのアルゴリズムが同等である」問題に関連しています。しかし、コンテキストは制限されており、セット、結合、副選択の基本的な操作のみが私のスコープ内にあります。
guettli 2015

3

定義によって有限時間で意味論的同等性をチェックすることは不可能です。ライスの定理を参照してください:

部分関数の重要なプロパティの場合、アルゴリズムがそのプロパティを使用して部分関数を計算するかどうかを決定する一般的で効果的な方法はありません。


2
これは単なるコメントではありません。ライスのこのコンテキストへの適用性を拡大していただけますか。
マイケルグリーン

理論的には可能であったとしても、現在のSQL標準構文は非常にバロックなので、実際には不可能です
James Anderson

1
OPの説明では、問題は意味的同等性よりも論理的同等性についてのように見えます。本当の問題は、SQLステートメントを数式に変換してから、論理的同等性を評価できるかどうかです。
ForguesR 2015

2

dbaユーザーLennartが私にこのプロジェクトを指摘しました。

http://cosette.cs.washington.edu/

Cosetteは、SQLクエリの同等性をチェックするための自動証明ツールです。これは、SQLの実質的なフラグメントをCoq Proof AssistantとRosetteシンボリック仮想マシンで形式化します。これは、指定されたクエリのペアの同等性の正式な証明または反例のいずれかを返します。


1

これを行う1つの方法は、パーサーを作成するか、既存のパーサーを使用することです。C#にはTSQLParserクラスがあり、Parse()メソッドがあると思います。パーサーはクエリをサブクラスに分割し、比較できるようにします。


1

セット理論に基づく同等性テストを探している場合、最善の策はWHERE、タイプJOIN(内部または外部)に変換できる条件を変換し、ステートメントをリファクタリングすることです。これは、IN subselectEXISTS subselectの他の条件とWHERE単語を含む句をSELECT。両方のSQLステートメントでこれを実行すると、FROM関心のあるセットベースのロジック/数学を表す新しい句ができます。その後、2つのステートメントを視覚的に比較できます。これをすべて自動化する方法を探しているのなら、これを正確に行うことができるツールはわかりません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.