私のSQLストアドプロシージャでパフォーマンスの問題が発生しています。主にカーソルが原因です。しかし、私はSQLストアドプロシージャのループを作るための別の方法について考えることはできません。今では、サーバーの複数のスレッドを使用して、プロシージャにパフォーマンスを向上させる方法がありますか?複数のスレッドを使用するストアドプロシージャ
は、ここに私のストアドプロシージャのための私のカーソルです:あなたはセットベースのソリューションを使用する必要があるときは、カーソルを使用している
DECLARE FILE_CURSOR CURSOR FOR
SELECT filenumber
FROM [fmsStage].[dbo].[file]
WHERE relationcode = @relationCode
OPEN FILE_CURSOR
FETCH NEXT FROM FILE_CURSOR INTO @fileID
WHILE @@FETCH_STATUS = 0
BEGIN
/**** Fetch data from outgoinginvoiceline for RelationCode and FileNumber ****/
SET @amount = (SELECT DISTINCT Sum(cnt)
FROM (SELECT Sum([fms].[dbo].[outgoinginvoiceline].[amount]) cnt
FROM [fms].[dbo].[outgoinginvoiceline]
WHERE [fms].[dbo].[outgoinginvoiceline].[filenumber] = CONVERT(NVARCHAR, @fileID)
AND [fms].[dbo].[outgoinginvoiceline].[relationcode] = @relationCode
UNION ALL
SELECT Sum([fmsAir].[dbo].[outgoinginvoiceline].[amount]) cnt
FROM [fmsAir].[dbo].[outgoinginvoiceline]
WHERE [fmsAir].[dbo].[outgoinginvoiceline].[filenumber] = CONVERT(NVARCHAR, @fileID)
AND [fmsAir].[dbo].[outgoinginvoiceline].[relationcode] = @relationCode
UNION ALL
SELECT Sum([fmsProjects].[dbo].[outgoinginvoiceline].[amount]) cnt
FROM [fmsProjects].[dbo].[outgoinginvoiceline]
WHERE [fmsProjects].[dbo].[outgoinginvoiceline].[filenumber] = CONVERT(NVARCHAR, @fileID)
AND [fmsProjects].[dbo].[outgoinginvoiceline].[relationcode] = @relationCode) AS counted)
/**** Get the currency from the database ****/
SET @currency = (SELECT TOP 1 [fms].[dbo].[outgoinginvoiceline].[currency]
FROM [fms].[dbo].[outgoinginvoiceline]
WHERE [fms].[dbo].[outgoinginvoiceline].[filenumber] = CONVERT(NVARCHAR, @fileID)
AND [fms].[dbo].[outgoinginvoiceline].[relationcode] = @relationCode)
/**** If the currency is not EURO then use the currencyrate on it, by default the currencyrate is 1.00 ****/
IF @currency != 'EUR'
BEGIN
SET @currencyRate = (SELECT TOP 1 [fms].[dbo].[outgoinginvoiceline].[rate]
FROM [fms].[dbo].[outgoinginvoiceline]
WHERE [fms].[dbo].[outgoinginvoiceline].[filenumber] = CONVERT(NVARCHAR, @fileID)
AND [fms].[dbo].[outgoinginvoiceline].[relationcode] = @relationCode)
END
/**** If @amount is NULL (empty) then we set it to zero because adding NULL creates issues ****/
IF @amount IS NULL
BEGIN
SET @amount = 0
END
/**** Do the amount times currencyRate ****/
SET @amount = @amount * @currencyRate
/**** Add the new amount to the total previous amount ****/
SET @totalAmount = @totalAmount + @amount
/**** Fetch data from outgoinginvoiceline for RelationCode and FileNumber ****/
SET @amount2 = (SELECT DISTINCT Sum(cnt)
FROM (SELECT Sum([fms].[dbo].[outgoinginvoiceline].[amount]) cnt
FROM [fms].[dbo].[outgoinginvoiceline]
WHERE [fms].[dbo].[outgoinginvoiceline].[filenumber] = CONVERT(NVARCHAR, @fileID)
UNION ALL
SELECT Sum([fmsAir].[dbo].[outgoinginvoiceline].[amount]) cnt
FROM [fmsAir].[dbo].[outgoinginvoiceline]
WHERE [fmsAir].[dbo].[outgoinginvoiceline].[filenumber] = CONVERT(NVARCHAR, @fileID)
UNION ALL
SELECT Sum([fmsProjects].[dbo].[outgoinginvoiceline].[amount]) cnt
FROM [fmsProjects].[dbo].[outgoinginvoiceline]
WHERE [fmsProjects].[dbo].[outgoinginvoiceline].[filenumber] = CONVERT(NVARCHAR, @fileID)) AS counted)
/**** Get the currency from the database ****/
SET @currency2 = (SELECT TOP 1 [fms].[dbo].[outgoinginvoiceline].[currency]
FROM [fms].[dbo].[outgoinginvoiceline]
WHERE [fms].[dbo].[outgoinginvoiceline].[filenumber] = CONVERT(NVARCHAR, @fileID))
/**** If the currency is not EURO then use the currencyrate on it, by default the currencyrate is 1.00 ****/
IF @currency2 != 'EUR'
BEGIN
SET @currencyRate2 = (SELECT TOP 1 [fms].[dbo].[outgoinginvoiceline].[rate]
FROM [fms].[dbo].[outgoinginvoiceline]
WHERE [fms].[dbo].[outgoinginvoiceline].[filenumber] = CONVERT(NVARCHAR, @fileID))
END
/**** If @amount is NULL (empty) then we set it to zero because adding NULL creates issues ****/
IF @amount2 IS NULL
BEGIN
SET @amount2 = 0
END
/**** Do the amount times currencyRate ****/
SET @amount2 = @amount2 * @currencyRate2
/**** Add the new amount to the total previous amount ****/
SET @totalAmount2 = @totalAmount2 + @amount2
FETCH NEXT FROM FILE_CURSOR INTO @fileID
END
大部分の場合、カーソルを使用するのではなく、「セットベースのロジック」を使用して目的を達成する方法があります。まず、カーソルではなくSQLクエリーを使って何をしようとしているのかを再現しようとします。 – Jeremy
あなたのような場合は、マルチスレッド化は役に立ちません。 Jeremyが指摘しているように、最良の方法は、あなたの問題に対するセットベースのアプローチを策定することです。 –