日期:2014-05-17  浏览次数:20527 次

哪个SQL执行效率高?
两张表
T_3G_TEST(PRD_INST_ID,BYTES_3G) PRD_INST_ID上聚簇索引
T_QD_HLF(PRD_INST_ID,AREA_NAME,...) PRD_INST_ID上聚簇索引、AREA_NAME上非聚簇索引
两张表都有500W左右数据,想要对AREA_NAME为'ZL'的PRD_INST_ID对应的BYTES_3G进行求和,三种做法执行计划完全一样,我表示不理解。 

第1种:
SELECT  SUM(a.BYTES_3G)
FROM    dbo.T_3G_TEST a ,
        dbo.T_QDHLF b
WHERE   a.PRD_INST_ID = b.PRD_INST_ID
        AND b.AREA_NAME = 'ZL'
第2种:
SELECT  SUM(a.BYTES_3G)
FROM    dbo.T_3G_TEST a
WHERE   EXISTS ( SELECT 1
                 FROM   T_QDHLF b
                 WHERE  a.PRD_INST_ID = b.PRD_INST_ID
                        AND b.AREA_NAME = 'ZL' )
第3种:
SELECT  SUM(a.BYTES_3G)
FROM    dbo.T_3G_TEST a
WHERE   PRD_INST_ID IN ( SELECT PRD_INST_ID
                         FROM   T_QDHLF b
                         WHERE  b.AREA_NAME = 'ZL' )

------最佳解决方案--------------------
都一样,
主要是你的where 条件不复杂
而且返回的结果也只有一个聚合值

所以对三个语句优化后的方案都是一样的。
------其他解决方案--------------------
不要光看语句,因为索引、统计信息等等都会影响查询。打开set statistics io on 来监控io,并打开执行计划,然后两者做对比,由于查询优化器会做一些调整,所以不排除多个查询在交给存储引擎的时候已经变成了同一个查询。另外由于数据分布的不同,简单的修改可能有非常大的性能差异。比如order by是asc还是desc,经常会有很大的差异。
------其他解决方案--------------------
试试临时表 ,然后 exists 
SELECT PRD_INST_ID  into #B
FROM   T_QDHLF b 
 WHERE  b.AREA_NAME = 'ZL'
------其他解决方案--------------------
因为实际的执行计划是一样的.

------其他解决方案--------------------
看一下查询计划
------其他解决方案--------------------
自己试试不就知道了么?