2016-09-24 8 views
-1

Meine Datenbank enthält zwei Tabellen mit den Namen DomesticSalesOrders und InternationalSalesOrders. Beide Tabellen enthalten mehr als 100 Millionen Zeilen. Jede Tabelle hat eine Primärschlüsselspalte mit dem Namen SalesOrderId. Die Daten in den beiden Tabellen unterscheiden sich voneinander.SQL Union Alle Fragen

Geschäftsbenutzer möchten einen Bericht, der zusammengefasste Informationen über die Gesamtzahl der globalen Verkäufe und Gesamtumsatzbeträge enthält. Ich muss sicherstellen, dass meine Abfrage in der minimal möglichen Zeit ausgeführt wird. Welche Abfrage soll ich verwenden?

Option 1:

SELECT 
    COUNT(*) AS NumberOfSales, 
    SUM(SalesAmount) AS TotalSalesAmount 
FROM 
(
    SELECT 
     SalesOrderId, 
     SalesAmount 
    FROM 
     DomesticSalesOrders 

    UNION ALL 

    SELECT 
     SalesOrderId, 
     SalesAmount 
    FROM 
     InternationalSalesOrders 
) AS p 

Option 2:

SELECT 
    COUNT(*) AS NumberOfSales, 
    SUM(SalesAmount) AS TotalSalesAmount 
FROM 
    DomesticSalesOrders 

UNION ALL 

SELECT 
    COUNT(*) AS NumberOfSales, 
    SUM(SalesAmount) AS TotalSalesAmount 
FROM 
    InternationalSalesOrders 

Ich denke, beide korrekt sind, aber ich kann nicht verstehen, was anders ist? Dank

+3

Haben Sie es versucht? Welche Ergebnisse haben Sie beobachtet? – nicomp

+1

Das klingt nach einer Hausaufgabe. – Dai

Antwort

0

Die erste Antwort ist richtig, weil es nur eine einzige Zeile zurückgibt:

NumberOfSales  | TotalSalesAmount 
---------------------+---------- 
COUNT(of subquery) | SUM(of subquery) 

Während die zweite Antwort gibt zwei Reihen:

NumberOfSales   | TotalSalesAmount 
-----------------------+---------- 
COUNT(of subquery 1) | SUM(of subquery 1) 
COUNT(of subquery 2) | SUM(of subquery 2) 

Eine bessere Antwort wäre, die Split- zu verwenden Unterabfragen von Option 2, um die Parallelisierung auszunutzen, und schließlich eine zweite Aggregationsebene berechnen:

SELECT 
    SUM([inner].NumberOfSales) AS NumberOfSales, 
    SUM([inner].SalesAmount ) AS TotalSalesAmount 
FROM 
(
    SELECT 
     COUNT(*) AS NumberOfSales, 
     SUM(SalesAmount) AS TotalSalesAmount 
    FROM 
     DomesticSalesOrders 

    UNION ALL 

    SELECT 
     COUNT(*) AS NumberOfSales, 
     SUM(SalesAmount) AS TotalSalesAmount 
    FROM 
     InternationalSalesOrders 
) AS [inner] 

Natürlich müssten Sie sehen, wie Ihr RDBMS es ausführt und Ausführungspläne vergleichen. Eine intelligente Engine würde für diese Abfrage den gleichen Ausführungsplan generieren wie für Option 1 in Ihrer Frage, aber Sie können diese Annahme nicht immer treffen.

+0

Lieber Dai, deine Antwort ist sehr hilfreich, danke! –