WEB开发网
开发学院数据库MySQL MySQL数据库中对子查询的限制 阅读

MySQL数据库中对子查询的限制

 2007-10-29 11:01:38 来源:WEB开发网   
核心提示: DELETE FROM t WHERE ... (SELECT ... FROM t ...);UPDATE t ... WHERE col = (SELECT ... FROM t ...);{INSERT|REPLACE} INTO t (SELECT ... FROM t ...);

DELETE FROM t WHERE ... (SELECT ... FROM t ...);
UPDATE t ... WHERE col = (SELECT ... FROM t ...);
{INSERT|REPLACE} INTO t (SELECT ... FROM t ...);

例外:如果为FROM子句中更改的表使用子查询,前述禁令将不再适用。例如:

UPDATE t ... WHERE col =
(SELECT (SELECT ... FROM t...) AS _t ...);

禁令在此不适用,这是因为FROM中的子查询已被具体化为临时表,因此“t”中的相关行已在满足“t”条件的情况下、在更新时被选中。

与子查询相比,针对联合的优化程序更成熟,因此,在很多情况下,如果将其改写为join(联合),使用子查询的语句能够更有效地执行。

但下述情形例外:IN子查询可被改写为SELECT DISTINCT联合。例如:

SELECT col FROM t1 WHERE id_col IN
(SELECT id_col2 FROM t2 WHERE condition);

可将该语句改写为:

SELECT DISTINCT col FROM t1,
t2 WHERE t1.id_col = t2.id_col AND condition;

但在该情况下,联合需要额外的DISTINCT操作,而且与子查询相比,效率并不高。

可能的未来优化:MySQL不改写针对子查询评估的联合顺序。在某些情况下,如果MySQL将其改写为联合,能够更有效地执行子查询。这样,优化程序就能在更多的执行方案间进行选择。例如,它能决定是否首先读取某一表或其他。

例如:

SELECT a FROM outer_table AS ot
WHERE a IN (SELECT a FROM inner_table AS it WHERE ot.b = it.b);

对于该查询,MySQL总会首先扫描outer_table,如然后针对每一行在inner_table上执行子查询。如果outer_table有很多行而inner_table只有少量行,查询的执行速度或许要慢于本应有的速度。

Tags:MySQL 数据库 对子

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接