2015-12-23 46 views
0

我正在用2个派生表(或者你可以称之为子查询)和WHERE子句来写一个查询来筛选,但我不知道在哪里我应该放置WHERE子句来优化性能。请看下面的例子: (我肯定知道这是一个愚蠢的例子,但它可以帮助来形容我的问题)我应该把WHERE子句放在子查询中(派生表)吗

SELECT * 
FROM 
    (SELECT id FROM A) A 
    JOIN 
    (SELECT id FROM B) B 
    ON A.id = B.id 
WHERE A.id = 1 

VS

SELECT * 
FROM 
    (SELECT id FROM A 
    WHERE A.id = 1 
    ) A 
    JOIN 
    (SELECT id FROM B 
    WHERE B.id = 1 
    ) B 
    ON A.id = B.id 

从性能的角度来看,它的问题在哪里放置WHERE子句? 我的数据库太小了,所以在测试查询时我没有看到任何区别。 谢谢。

+5

什么阻止您从A.id = b.ID上的JOIN B做SELECT * WHERE A.Id = 1? – wentimo

+0

那么,第二个甚至没有有效的语法 – Paparazzi

+0

纠正了他。 – trincot

回答

0

测试过这个 - 顶部查询有where子句在嵌套select之外,下部查询在嵌套select中有where子句。这个测试是用200k行完成的。我怀疑表现的差异可以忽略不计。

enter image description here

+0

请分享用于生成执行计划的脚本。查询,表格定义等我期望在这些计划之间完全没有区别。 –

+0

使用了他询问的确切疑问,我认为这很明显。 –

1

既不如果能避免它
似乎没有要在需要派生
这个例子特定需要您做出更复杂的好像查询优化器有更多的机会不最好的事情

这仅仅是一个真正疯狂的查询,但

SELECT A.id 
FROM A 
JOIN B 
     on A.id = B.ID 
    and A.id = 1 

SELECT A.id FROM A where A.Id = 1 
intersection 
SELECT B.id FROM B where B.Id = 1 

如果你打算做一个派生的话,那么我通常会从where派生出来。发生在你身上的事情是,在复杂的查询中,优化器会变得愚蠢,并且会发生一堆循环连接。如果它变得愚蠢并且执行一堆循环,你甚至可能最终将子实体化为#temp。

+0

派生表不会“杀死索引” - 容易让您自己测试。 –

+0

谢谢兄弟。我绝对知道这个查询是疯了,但我只是试图用这个愚蠢的例子来描述我的问题。我正在处理的真实查询要复杂得多,并且会让每个人都确信。 :) –

+0

我通常会从where中导出。发生在你身上的事情是,在复杂的查询中,优化器会对你产生愚蠢的感觉,并进行一堆循环连接。如果它变得愚蠢并且执行一堆循环,你甚至可能最终将实现物化为#temp。 – Paparazzi