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 ?

Nguyen Ca viết 12:14 ngày 01/10/2018

chú phải biết nó chậm ở đâu đã:
chạy Query Execution Plan trước để xem.

stackoverflow.com
Justin

How do I obtain a Query Execution Plan?

sql, sql-server, performance, tsql
asked by Justin on 09:37AM - 09 Sep 11

Đẵng Nguyễn Quốc viết 12:11 ngày 01/10/2018

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 ạ ?

Nguyen Ca viết 12:15 ngày 01/10/2018

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

Dark.Hades viết 12:03 ngày 01/10/2018

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.

Đẵng Nguyễn Quốc viết 12:08 ngày 01/10/2018

ý 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ả ?

Bài liên quan
0