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

SELECT + COUNT() 好迷茫,求解



SELECT Name,
      (SELECT COUNT(*) FROM SalesOrderDetail S
      WHERE S.ProductID=P.ProductID) AS SalesAmount
FROM Product P


我想问一下, 这个嵌套查询是逐行处理的吗?
是不是每次外部查询滚动一行,内部子查询就要遍历整个table?
是不是类似C语言里的嵌套循环:


for( int P_Name = 0; P_Name < N; P_Name++)
    for( int S_ID = 0; S_ID < M; S_ID++ )
         if ( P_ID == S_ID )
             printf( '%s', Name );


我的理解有问题吗?

------解决方案--------------------
这样写试试,性能应该有所提升..

select p.Name,
       isnull(s.SalesAmount,0) 'SalesAmount'
from Product p
left join
(select ProductID,
        count(1) 'SalesAmount' 
 from SalesOrderDetail
 group by ProductID
) s on p.ProductID=s.ProductID

------解决方案--------------------
SELECT ProductName,
      (SELECT COUNT(*) FROM SalesOrderDetail S
      WHERE S.ProductID=P.ProductID) AS SalesAmount
FROM Product P

其查询计划如下


select P.ProductName,S.num from 
(
SELECT ProductID,COUNT(*) as num FROM SalesOrderDetail
group by ProductID
)S inner join Product P
on S.ProductID=P.ProductID

其查询计划如下

从两个查询计划可以看出,第一个SQL主要的开销都耗损在扫描表上,如果表数据量很大,第一个的查询效率肯定不如第二个SQL。因此楼主无须迷茫,还是用第二个SQL的写法。