SQL优化器/执行计划 - 重复的子查询

时间:2013-03-25 15:04:00

标签: sql sqlite query-optimization

注意:我目前正在sqlite3数据库上运行我的查询,但是欢迎来自任何其他DBMS的专业知识的答案......

我想知道查询优化器是否会尝试识别重复的查询/子查询,如果是这样的话,只运行一次。

以下是我的示例查询:

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

只运行一次(并将其结果缓存以供进一步访问)?

在这个例子中它不是什么大问题,因为它只执行了两次简单的查询,但我需要它才能运行 在我的实际程序中大约4-5次(x2,每个子记录两次,所以8-10真的)(它抓住所有子记录(table1) 与父记录(table2)相关联,由外键绑定。它还检查id映射表以确保它查询 对于本地生成的id,以及real / updated / new key)。

我非常感谢您的帮助,谢谢。

2 个答案:

答案 0 :(得分:1)

正如您要求其他DB的见解......

在Oracle DBMS中,任何独立子查询只执行一次。

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.

答案 1 :(得分: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和观点;如果性能确实很重要,最好的办法是为子查询的结果创建一个临时表。