Wir haben eine langsame Abfrage in unserem Altsystem gefunden. Was ich in der Abfrage sehe, ist ein doppeltes Fragment. Hier ist die vollständige Abfrage:Abfrageoptimierung. Doppelte Unterabfragen
DECLARE @SellerId INT;
DECLARE @DateFrom DATETIME;
DECLARE @DateTo DATETIME;
SET @SellerId = 5396884;
SET @DateFrom = '2016-01-05';
SET @DateTo = '2016-10-08';
DECLARE @CurrentDate DATETIME;
SET @CurrentDate = GETDATE();
CREATE TABLE #ReportDate (codes INT, dates DATETIME);
DECLARE @dif as INT;
DECLARE @cont as INT;
DECLARE @currdate as DATETIME;
SET @dif = DATEDIFF(day, @DateFrom, @DateTo);
SET @cont = 1;
SET @currdate = @DateFrom - 1;
WHILE (@cont <= @dif + 1)
BEGIN
SET @currdate = DATEADD(DAY, 1, @currdate);
INSERT INTO #ReportDate VALUES (@cont, @currdate);
SET @cont = @cont + 1;
END
/* HOW TO OPTIMIZE THIS ONE? */
SELECT
#ReportDate.dates as valid_date,
(
SELECT
COUNT(DISTINCT(nonCancelledSales.num_remito)) as actives
FROM
(
SELECT *
FROM salesView
WHERE
salesView.sell_id NOT IN
(
SELECT sell_id
FROM salesStates
WHERE
salesStates.aborted = 1
)
) nonCancelledSales
WHERE
nonCancelledSales.seller_id = @SellerId AND
nonCancelledSales.cancelled = 0 AND
nonCancelledSales.void = 0 AND
nonCancelledSales.hasDiscount = 0 AND
nonCancelledSales.dateOfSale <= #ReportDate.dates AND
nonCancelledSales.currentState = (SELECT MAX(hveest.date)
FROM salesStates hveest
WHERE
hveest.sell_id = nonCancelledSales.sell_id AND
hveest.date <= #ReportDate.dates) AND
nonCancelledSales.lastProductDate = (SELECT MAX(hvepro.date)
FROM productHistory hvepro
WHERE
hvepro.sell_id = nonCancelledSales.sell_id AND
hvepro.date <= #ReportDate.dates)
) total_actives,
(
SELECT
ISNULL(SUM(nonCancelledSales.paymentValue),0) as active
FROM
(
SELECT *
FROM salesView
WHERE
salesView.sell_id NOT IN
(
SELECT sell_id
FROM salesStates
WHERE
salesStates.aborted = 1
)
) nonCancelledSales
WHERE
nonCancelledSales.seller_id = @SellerId AND
nonCancelledSales.cancelled = 0 AND
nonCancelledSales.void = 0 AND
nonCancelledSales.hasDiscount = 0 AND
nonCancelledSales.dateOfSale <= #ReportDate.dates AND
nonCancelledSales.currentState = (SELECT MAX(hveest.date)
FROM salesStates hveest
WHERE
hveest.sell_id = nonCancelledSales.sell_id AND
hveest.date <= #ReportDate.dates) AND
nonCancelledSales.lastProductDate = (SELECT MAX(hvepro.date)
FROM productHistory hvepro
WHERE
hvepro.sell_id = nonCancelledSales.sell_id AND
hvepro.date <= #ReportDate.dates)
) active
FROM
#ReportDate
GROUP BY
#ReportDate.dates
DROP TABLE #ReportDate
Hier sind die beiden duplizierten Fragmente ich sehe:
(
SELECT
COUNT(DISTINCT(nonCancelledSales.num_remito)) as actives
FROM
(
SELECT *
FROM salesView
WHERE
salesView.sell_id NOT IN
(
SELECT sell_id
FROM salesStates
WHERE
salesStates.aborted = 1
)
) nonCancelledSales
WHERE
nonCancelledSales.seller_id = @SellerId AND
nonCancelledSales.cancelled = 0 AND
nonCancelledSales.void = 0 AND
nonCancelledSales.hasDiscount = 0 AND
nonCancelledSales.dateOfSale <= #ReportDate.dates AND
nonCancelledSales.currentState = (SELECT MAX(hveest.date)
FROM salesStates hveest
WHERE
hveest.sell_id = nonCancelledSales.sell_id AND
hveest.date <= #ReportDate.dates) AND
nonCancelledSales.lastProductDate = (SELECT MAX(hvepro.date)
FROM productHistory hvepro
WHERE
hvepro.sell_id = nonCancelledSales.sell_id AND
hvepro.date <= #ReportDate.dates)
) total_actives,
(
SELECT
ISNULL(SUM(nonCancelledSales.paymentValue),0) as active
FROM
(
SELECT *
FROM salesView
WHERE
salesView.sell_id NOT IN
(
SELECT sell_id
FROM salesStates
WHERE
salesStates.aborted = 1
)
) nonCancelledSales
WHERE
nonCancelledSales.seller_id = @SellerId AND
nonCancelledSales.cancelled = 0 AND
nonCancelledSales.void = 0 AND
nonCancelledSales.hasDiscount = 0 AND
nonCancelledSales.dateOfSale <= #ReportDate.dates AND
nonCancelledSales.currentState = (SELECT MAX(hveest.date)
FROM salesStates hveest
WHERE
hveest.sell_id = nonCancelledSales.sell_id AND
hveest.date <= #ReportDate.dates) AND
nonCancelledSales.lastProductDate = (SELECT MAX(hvepro.date)
FROM productHistory hvepro
WHERE
hvepro.sell_id = nonCancelledSales.sell_id AND
hvepro.date <= #ReportDate.dates)
) active
Ist es völlig notwendig, um die Abfrage zu duplizieren? Er ist in dem ersten bekommen:
COUNT(DISTINCT(nonCancelledSales.num_remito)) as actives
auf dem zweiten:
ISNULL(SUM(nonCancelledSales.paymentValue),0) as active
Ich nehme an, es hat eine Möglichkeit, um die Abfrage neu zu schreiben, aber ich bin nicht sicher, wie.
sieht aus wie es war eine einzige Abfrage auf einmal, die würde erklären die 'GROUP BY # ReportDate.dates' – JamieD77
Sie könnten auch beschleunigen, indem Sie diese Schleife und stattdessen eine Tally-Tabelle verwenden, um Ihre Liste der Daten zu füllen. Dies ist wahrscheinlich nicht der schlechteste Teil der Leistung, aber es ist super einfach, dieses Set basierend auf einer Schleife zu erstellen. Hier ist ein großer Artikel, der Tally-Tabellen erklärt und wie sie Loops ersetzen können. http://www.sqlservercentral.com/articles/T-SQL/62867/ –
@ JamieD77 sagst du die Gruppe von ist überflüssig? –