0

注:現在、問題のクエリをsqlite3 DBで実行していますが、他のDBMSの専門知識からの回答は歓迎すべき洞察になります...

クエリオプティマイザが、繰り返されるクエリ/サブクエリを識別し、実行する場合は1回だけ実行しようとするのではないかと思いました。

これが私の例のクエリです:

SELECT *
  FROM table1 AS t1
 WHERE t1.fk_id =
 (
    SELECT t2.fk_id
      FROM table2 AS t2
     WHERE t2.id = 1111
 )
 OR t1.fk_id =
 (
    SELECT local_id 
      FROM ID_MAP
     WHERE remote_id =
     (
        SELECT t2.fk_id
          FROM table2 AS t2
         WHERE t2.id = 1111
     )
 );

ネストされたクエリ

SELECT t2.fk_id
  FROM table2 AS t2
 WHERE t2.id = 1111

一度だけ実行されます(そしてその結果はさらにアクセスするためにキャッシュされます)?

この例では、2回しか実行されない単純なクエリであるため、大したことではありませんが、実際のプログラムでは、さらに4〜5回(x2、子レコードごとに2回、実際には8〜10回)実行する必要があります。 (外部キーによってバインドされた、親レコード(table2)に関連付けられたすべての子レコード(table1)を取得します。また、IDマッピングテーブルをチェックして、ローカルで生成されたIDと実際の/更新されたIDの両方をクエリすることを確認します。 /新しいキー)。

私はこれでどんな助けにも本当に感謝します、ありがとう。

4

2 に答える 2

1

他のDBからの洞察を求めたように...

Oracle DBMSでは、独立したサブクエリは1回だけ実行されます。

SELECT t2.fk_id
  FROM table2 AS t2
 WHERE t2.id = 1111  -- The result will be the same for any row in t1.

もちろん、依存するサブクエリは繰り返し実行する必要があります。

依存サブクエリの例:

SELECT t2.fk_id
  FROM table2 AS t2
 WHERE t2.id = t1.t2_id  -- t1.t2_id will have different values for different rows in t1.
于 2013-03-25T15:33:02.827 に答える
1

SQLiteには非常に単純なクエリオプティマイザがあり、同一のサブクエリを検出しようとさえしません。

> create table t(x);
> explain query plan
  select * from t
  where x in (select x from t) or
        x in (select x from t);
0|0|0|SCAN TABLE t (~500000 rows)
0|0|0|EXECUTE LIST SUBQUERY 1
1|0|0|SCAN TABLE t (~1000000 rows)
0|0|0|EXECUTE LIST SUBQUERY 2
2|0|0|SCAN TABLE t (~1000000 rows)

同じことがCTEとビューにも当てはまります。パフォーマンスが実際に重要である場合、最善の策は、サブクエリの結果の一時テーブルを作成することです。

于 2013-03-25T15:50:16.647 に答える