01/10/2018, 10:00
Cần giúp đỡ tối ưu SQL Query giảm thời gian truy vấn
SELECT
A.SlpName
,A.[Year]
,A.Region
,A.RegionName
,A.CardCode
,A.CardName
,A.[Type]
,SUM(A.AmtBefDi) AS AmtBefDi
FROM
(
--New
SELECT
T1.SlpName
,T.[Year]
,T.Region
,dbo.fn_GetRegionName(T.Region) AS RegionName
,T.CardCode
,T.CardName
,'New' AS [Type]
, SUM(T.AmtBefDi) AS AmtBefDi
FROM dbo.DTS_SUMMARY_SALES_AR AS T
LEFT JOIN DB_SAP.dbo.OSLP AS T1 ON T1.SlpCode = T.SlpCode
WHERE T1.Locked != 'Y'
AND T.Legal = @Legal
AND NOT EXISTS( SELECT T1.CardCode
FROM dbo.DTS_SUMMARY_SALES_AR AS T1
WHERE T.CardCode = T1.CardCode
AND T1.[Year] < T.[Year] - 1
AND T1.Legal = @Legal
GROUP BY T1.CardCode
HAVING COUNT(T1.CardCode) > 0)
GROUP BY T.SlpCode
,T1.SlpName
,T.[Year]
,T.Region
,T.CardCode
,T.CardName
UNION ALL
--Loss
SELECT
T1.SlpName
,T.[Year] + 1 AS [Year]
,T.Region
,dbo.fn_GetRegionName(T.Region) AS RegionName
,T.CardCode
,T.CardName
,'Loss' AS [Type]
, SUM(T.AmtBefDi) AS AmtBefDi
FROM dbo.DTS_SUMMARY_SALES_AR AS T
LEFT JOIN DB_SAP.dbo.OSLP AS T1 ON T1.SlpCode = T.SlpCode
WHERE T1.Locked != 'Y'
AND T.Legal = @Legal
AND T.[Year] < @Year
AND NOT EXISTS( SELECT T1.CardCode
FROM dbo.DTS_SUMMARY_SALES_AR AS T1
WHERE T.CardCode = T1.CardCode
AND T1.[Year] = @Year
AND T1.Legal = @Legal
GROUP BY T1.CardCode HAVING COUNT(T1.CardCode) > 0)
GROUP BY T.SlpCode
,T1.SlpName
,T.[Year]
,T.Region
,T.CardCode
,T.CardName
UNION ALL
--Remain
SELECT
T2.SlpName
,T.[Year]
,T.Region
,dbo.fn_GetRegionName(T.Region) AS RegionName
,T.CardCode
,T.CardName
,'Remain' AS [Type]
, SUM(T.AmtBefDi) AS AmtBefDi
FROM dbo.DTS_SUMMARY_SALES_AR AS T
INNER JOIN ( SELECT T1.CardCode , T1.SlpCode
FROM dbo.DTS_SUMMARY_SALES_AR AS T1
WHERE T1.[Year] < @Year AND T1.Legal = @Legal
GROUP BY T1.CardCode , T1.SlpCode
HAVING COUNT(T1.CardCode) > 0) T1 ON T1.CardCode = T.CardCode AND T1.SlpCode = T.SlpCode
LEFT JOIN DB_SAP.dbo.OSLP AS T2 ON T2.SlpCode = T.SlpCode
WHERE T2.Locked != 'Y'
AND T.Legal = @Legal
GROUP BY
T.SlpCode
,T2.SlpName
,T.[Year]
,T.Region
,T.CardCode
,T.CardName
UNION ALL
--Back
SELECT
T2.SlpName
,T.[Year]
,T.Region
,dbo.fn_GetRegionName(T.Region) AS RegionName
,T.CardCode
,T.CardName
,'Back' AS [Type]
, SUM(T.AmtBefDi) AS AmtBefDi
FROM dbo.DTS_SUMMARY_SALES_AR AS T
INNER JOIN ( SELECT
T1.CardCode
FROM dbo.DTS_SUMMARY_SALES_AR AS T1
WHERE T1.Legal = @Legal
AND T1.[Year] < @Year - 1
GROUP BY
T1.CardCode
HAVING COUNT(T1.CardCode) > 0) T3 ON T3.CardCode = T.CardCode
LEFT JOIN DB_SAP.dbo.OSLP AS T2 ON T2.SlpCode = T.SlpCode
WHERE T2.Locked != 'Y'
AND T.Legal = @Legal
GROUP BY T.SlpCode
,T2.SlpName
,T.[Year]
,T.Region
,T.CardCode
,T.CardName
) A
GROUP BY
A.SlpName
,A.[Year]
,A.Region
,A.RegionName
,A.CardCode
,A.CardName
,A.[Type]
Em run thì nó chạy trừ khoảng 14- 17s . Không có biết có cách nào làm cho việc truy vấn nhanh ko ?
Store Procedure này em dùng để query ra những khách hàng mới, mất , trung thành, trở lại từ quá khứ đến hiện tại ?
Bài liên quan
chú phải biết nó chậm ở đâu đã:
stackoverflow.com
chạy Query Execution Plan trước để xem.
How do I obtain a Query Execution Plan?
Hôm qua đến nay em có tìm và chạy được nhưng không biết cách xem như thế nào, không biết anh có tài liệu bằng tiếng việt về nó không ạ ?
không em ơi, đấy là kiên thức anh nhớ khi học .NEt thôi, chứ không đụng nhiều vào SQL server
Theo mình thấy nếu lệnh nào tách được cho phía “chương trình” thì tách ra.
Lệnh truy vấn kia của bạn sử dụng khá nhiều truy vấn con nên khó mà đảm bảo tốc độ cho server sql được.
ý của bạn là mình viết function sql kiểu table trong sql rồi gọi nó trong store procedure hả ?