注意:我目前正在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)。
我非常感谢您的帮助,谢谢。
答案 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和观点;如果性能确实很重要,最好的办法是为子查询的结果创建一个临时表。