使用Oracle(如果重要)。这两个Select语句都会产生相同的最终结果,但哪一个更快?
SELECT * FROM tbl_A WHERE val IN (SELECT myField FROM tbl_B WHERE ... );
或者子查询中的SELECT DISTINCT会更好吗?
SELECT * FROM tbl_A WHERE val IN (SELECT DISTINCT myField FROM tbl_B WHERE ... );
谢谢!
答案 0 :(得分:1)
不需要DISTINCT,一般来说,将DISTINCT添加到SELECT语句会增加SQL Server的工作量。
查看两者的查询计划。当你执行DISTINCT选项时,你会得到一个额外的SORT节点吗?
答案 1 :(得分:1)
SELECT * FROM account_item WHERE instrument_id IN (SELECT instrument_id FROM instrument WHERE market_id=202)
SELECT * FROM account_item WHERE instrument_id IN (SELECT distinct instrument_id FROM instrument WHERE market_id=202)
不同之处没有区别(正如您可能猜到的那样),两者都给出了这个执行计划:
ALL_ROWS SELECT STATEMENT Cost = 703
1.1 HASH JOIN
2.1 INDEX FAST FULL SCAN PRF_INSTRUMENT_COMPANY
2.2 TABLE ACCESS FULL ACCOUNT_ITEM
有什么不同之处:
1)子选择的基数
SELECT * FROM account_item WHERE instrument_id IN (SELECT instrument_id FROM instrument WHERE symbol='MSFT')
ALL_ROWS SELECT STATEMENT Cost = 129
1.1 HASH JOIN
2.1 TABLE ACCESS BY INDEX ROWID INSTRUMENT
3.1 INDEX RANGE SCAN PRF_INSTRUMENT_MATCH
2.2 TABLE ACCESS FULL ACCOUNT_ITEM
2)你是否可以访问未编入索引的tbl_A列(又名select * hurts)
SELECT account_id FROM account_item WHERE instrument_id IN (SELECT distinct instrument_id FROM instrument WHERE market_id=202)
ALL_ROWS SELECT STATEMENT Cost = 608
1.1 HASH JOIN
2.1 INDEX FAST FULL SCAN PRF_INSTRUMENT_COMPANY
2.2 INDEX FAST FULL SCAN PRF_ACCOUNT_ITEM
3)一旦你有了良好的基数并访问了正在使用的索引中的列:
SELECT account_id FROM account_item WHERE instrument_id IN (SELECT instrument_id FROM instrument WHERE symbol='MSFT')
ALL_ROWS SELECT STATEMENT Cost = 33
1.1 HASH JOIN
2.1 TABLE ACCESS BY INDEX ROWID INSTRUMENT
3.1 INDEX RANGE SCAN PRF_INSTRUMENT_MATCH
2.2 INDEX FAST FULL SCAN PRF_ACCOUNT_ITEM
您的查询可以使用连接而不是子选择进行重写。
select a.account_id
from account_item a,
instrument i
where a.instrument_id=i.instrument_id
and i.symbol='MSFT'
ALL_ROWS SELECT STATEMENT Cost = 33
1.1 HASH JOIN
2.1 TABLE ACCESS BY INDEX ROWID INSTRUMENT
3.1 INDEX RANGE SCAN PRF_INSTRUMENT_MATCH
2.2 INDEX FAST FULL SCAN PRF_ACCOUNT_ITEM
使用示例表:
select a.*
from tbl_A,tbl_B
where a.val=b.myField
and b...some other condition
subselect与join的效率可以引发新的争论。 Oracle被广告,以便它可以将... subselect转换为连接,正如您所看到的,执行计划是相同的。然而情况并非总是这样,取决于您是否访问tbl_a(帐户项目)的未编入索引字段,或者tbl_b(工具)标准的基数,事情可能会非常奇怪。
基本上,经验法则是: