7

私は当初、1 を超える顧客ごとの年間総注文数を調べるクエリを作成しました。1.query では、結果セットをフィルター処理し、顧客名を検出した別の結果セットと結合しました。興味深いことに、最初にフィルターを使用すると、結合する必要がある結果が少なくなるため、パフォーマンスが向上すると思います。そこで、最初に結合してからフィルタする 2 番目のクエリを作成しました。これは、最初のクエリよりもきれいに見えます。結果のすべての時間が低いため、結果は期待どおりです。しかし、どの時間が最も重要なのかわかりません。それとも今回の事件は偶然?パフォーマンスをどう考えるか

use [AdventureWorks2012]
set statistics time on;

--1.filter first,join second
select tempC.*,tempP.FirstName,tempP.LastName
from 
(select  Year(OrderDate) As OrderYear,CustomerID,count(CustomerID) As CustomerOrderAmt
from Sales.SalesOrderHeader 
group by Year(OrderDate),CustomerID 
having count(CustomerID) >1
) as tempC
join(
select p.FirstName,p.LastName,c.CustomerID
from Person.Person as p join Sales.Customer as c on c.PersonID=p.BusinessEntityID
) as tempP
on tempC.CustomerID=tempP.CustomerID
order by tempC.OrderYear,tempC.CustomerID
GO

--2.join first,filter second

select Year(so.OrderDate) As Orderdate,so.CustomerID,count(so.CustomerID) As CustomerOrderAmt,p.FirstName,p.LastName
from Sales.SalesOrderHeader as so
join Sales.Customer as C on so.CustomerID=c.CustomerID
join Person.Person as p on c.PersonID=p.BusinessEntityID
group by Year(so.OrderDate),so.CustomerID,p.FirstName,p.LastName
having count(so.CustomerID)>1
go
4

2 に答える 2

4

結合操作の全体数とブロック GROUP BY 内の列の量を減らすことができるサブクエリを使用することをお勧めします。したがって、最初のクエリの方が確実に効率的であることをすぐにお伝えします。

クエリ:

SELECT  
      t.OrderYear
    , t.CustomerID
    , t.CustomerOrderAmt 
    , p.FirstName 
    , p.LastName
FROM ( 
     SELECT 
            OrderYear = YEAR(OrderDate)  
          , CustomerID 
          , CustomerOrderAmt = COUNT(CustomerID) 
     FROM Sales.SalesOrderHeader
     GROUP BY 
            YEAR(OrderDate) 
          , CustomerID
     HAVING COUNT(CustomerID) > 1
) t
JOIN ( 
     SELECT   
            p.FirstName 
          , p.LastName 
          , c.CustomerID
     FROM Person.Person p
     JOIN Sales.Customer c ON c.PersonID = p.BusinessEntityID
) p ON t.CustomerID = p.CustomerID
ORDER BY 
       t.OrderYear 
     , t.CustomerID

SELECT  
       Orderdate = YEAR(so.OrderDate)  
     , so.CustomerID 
     , CustomerOrderAmt = COUNT(so.CustomerID)  
     , FirstName = MAX(p.FirstName)
     , LastName = MAX(p.LastName)
FROM Sales.SalesOrderHeader so
JOIN Sales.Customer c ON so.CustomerID = c.CustomerID
JOIN Person.Person p ON c.PersonID = p.BusinessEntityID
GROUP BY 
       YEAR(so.OrderDate) 
     , so.CustomerID 
HAVING COUNT(so.CustomerID) > 1

クエリ費用:

クエリ費用

実行時間:

-- first query
SQL Server Execution Times:
   CPU time = 94 ms,  elapsed time = 395 ms.

-- second query   
SQL Server Execution Times:
   CPU time = 140 ms,  elapsed time = 480 ms.
于 2013-06-21T06:57:11.487 に答える