サブクエリ メソッドを使用して、選択した日付内の最後のレコードを見つけようとしています。問題は、クエリが遅すぎることです。このクエリを書き直してパフォーマンスを向上させる方法について誰かアイデアがあるかどうか疑問に思っています。このため、サーバーが死んでいます。
テストを容易にするために、テスト用の偽のデータを生成するテーブル変数を作成しました。このスクリプトをテストするには、usp_ExtractData'400000' を実行してください
私の懸念は --- セクション B です。私の結果は、400000*3 = 1200000 レコードに対して 18 秒でした。実際のデータベースでは、インデックスを作成し、毎晩インデックスを再作成します。
--Store proceedure with table variable data
ALTER PROCEDURE [dbo].[usp_ExtractData](
@TotalRecord int--Create random records for each product
)
AS
BEGIN
--MS SQL 2008
SET NOCOUNT ON;
--SECTION 1--Create test data--- GO TO SECTION 2
--Create Variable table to Products fake data
DECLARE @Product TABLE
(
ProductID int primary key not null
,SKU varchar(100) not null
)
--Insert couple records into @Product table
INSERT INTO @Product(ProductID, SKU) VALUES (100,'CUP100')
INSERT INTO @Product(ProductID, SKU) VALUES (101,'CUP101')
INSERT INTO @Product(ProductID, SKU) VALUES (102,'MUG101')
--Create Variable table to hold Products History data
DECLARE @History TABLE
(
ID int identity not null
,ProductID int not null
,VisitedDatetime datetime not null
)
--Generate random record for testing
WHILE @TotalRecord>0
BEGIN
INSERT INTO @History( ProductID, VisitedDatetime) VALUES (100,DATEADD(minute,rand()*100,GETDATE()))
INSERT INTO @History( ProductID, VisitedDatetime) VALUES (101,DATEADD(minute,rand()*100,GETDATE()))
INSERT INTO @History( ProductID, VisitedDatetime) VALUES (102,DATEADD(minute,rand()*100,GETDATE()))
set @TotalRecord=@TotalRecord-1
END
--SECTION 1--Finised creating test data
---SECTION B
--SELECTION B1- SEE DATA
SELECT * FROM @History ORDER BY ProductID, VisitedDatetime DESC
--Run query to find the last visit per each ProductID
--THIS IS TOO SLOW
DECLARE @TestPerformanceDatetime datetime--Test performance
SET @TestPerformanceDatetime= GETDATE()
SELECT *, (select top(1) VisitedDatetime FROM @History as t2 WHERE t2.ProductID=ProductID and VisitedDatetime BETWEEN GETDATE() AND GETDATE()+10 ORDER BY VisitedDatetime DESC) as LastVistiDate
FROM @Product
--Display the performance
SELECT DATEDIFF(SECOND, @TestPerformanceDatetime,getdate()) AS TotalSeconds
---SECTION B - End
END