1
select * from big_table 
        where big_table_column1 > (select max(another_table_column1) from another_table) 
        and   big_table_column1 < 100000000

max(another_table_column1) が 200000000 を返す場合、取得する行はありません。

次に、SQL Server 2008 R2 エンタープライズで実行すると、big_table からデータを取得するのに時間がかかるようです。

しかし、Oracleで実行すると、すぐに終了しました。

SQLサーバーはサブクエリの結果で動的に最適化を行っていないようですね。

ありがとう。

4

1 に答える 1

1

いいえ、サブクエリを評価した後、この矛盾を動的に検出しません。がインデックス化されていて、プランが範囲シークを示している場合big_table_column1、大きな違いはありませんが、そうでない場合は、クエリを分割して を使用することで最適化できますOPTION (RECOMPILE)

結合されたクエリは、大きなテーブルのフル スキャンを実行します。

ここに画像の説明を入力

2 つに分割することで、大きなテーブルにまったく触れないようにすることができます (コンスタント スキャンは、ステートメントが再コンパイルされたときに矛盾が検出されたことを示します)。

ここに画像の説明を入力

CREATE TABLE big_table
  (
     big_table_column1 INT
  )

INSERT INTO big_table
SELECT TOP 1000000 v1.number
FROM   master..spt_values v1,
       master..spt_values v2

CREATE TABLE another_table
  (
     another_table_column1 INT
  )

INSERT INTO another_table
VALUES      (200000000)

/*Query 1*/
SELECT *
FROM   big_table
WHERE  big_table_column1 > (SELECT MAX(another_table_column1)
                            FROM   another_table)
       AND big_table_column1 < 100000000
OPTION (RECOMPILE)

/*Query 2*/
DECLARE @another_table_column1 INT

SELECT @another_table_column1 = MAX(another_table_column1)
FROM   another_table

SELECT *
FROM   big_table
WHERE  big_table_column1 > @another_table_column1
       AND big_table_column1 < 100000000
OPTION (RECOMPILE)

DROP TABLE big_table, another_table 
于 2013-05-03T14:34:56.097 に答える