0

ストアドプロシージャを作成しました。これでパフォーマンスが非常に悪いことがわかりました。これはwhileループが原因だと思います。

ALTER PROCEDURE [dbo].[DeleteEmptyCatalogNodes] 
@CatalogId UNIQUEIDENTIFIER,
@CatalogNodeType int = null
AS
BEGIN
SET NOCOUNT ON;

DECLARE @CID UNIQUEIDENTIFIER
DECLARE @CNT int

SET @CID = @CatalogId
SET @CNT = @CatalogNodeType

DELETE cn FROM CatalogNodes cn
LEFT JOIN CatalogNodes as cnj on cn.CatalogNodeId = cnj.ParentId
LEFT JOIN CatalogArticles as ca on cn.CatalogNodeId = ca.CatalogNodeId
WHERE cn.CatalogId = @CID
AND cnj.CatalogNodeId IS NULL
AND ca.ArticleId IS NULL
AND (cn.CatalogNodeType = @CNT OR @CNT IS NULL)

WHILE (@@ROWCOUNT  > 0)
BEGIN
    DELETE cn FROM CatalogNodes cn
    LEFT JOIN CatalogNodes as cnj on cn.CatalogNodeId = cnj.ParentId
    LEFT JOIN CatalogArticles as ca on cn.CatalogNodeId = ca.CatalogNodeId
    WHERE cn.CatalogId = @CID
    AND cnj.CatalogNodeId IS NULL
    AND ca.ArticleId IS NULL
    AND (cn.CatalogNodeType = @CNT OR @CNT IS NULL)
END
END

もっと「設定」する方法についてヒントをくれる人はいますか?

どうもありがとう!

コメントと回答の編集:

テーブルは次のように作成されます。

カタログノード:

CatalogNodeId|ParentId|Name
1|NULL|Root
2|1|Node1
3|1|Node2
4|2|Node1.1

カタログ記事:

CatalogNodeId|Name
3|Article1
3|Article2
3|Article3

SP が呼び出された後、Node1 と Node1.1 を削除する必要があります。最初の delete ステートメントでは、Node1.1 が削除されます。While ループでは、Node1 が削除されます。私の問題が理解しやすくなったといいのですが、それはツリー構造です。

4

4 に答える 4

1

あなたのループは何もしません...最初のdeleteステートメントは、where条件に準拠するレコードがある場合、いくつかのレコードを削除します...したがって、@@rowcountは0より大きくなりますが、レコードはありませんループ内の 2 番目の delete ステートメントで削除する必要があります。または私は何かを逃しましたか?

とにかく、この delete を 2 回続けて実行しても、パフォーマンスに大きな影響があるとは思いません...クエリ プランを見ればわかるはずです...

于 2013-11-06T11:41:02.610 に答える
1

一致したすべての行が最初の DELETE ステートメントから削除されるため、WHILE 部分は必要ありません。

于 2013-11-06T11:37:03.720 に答える
0

私のポイントでこれを行う 1 つの方法は、テーブル変数を作成し、そこに削除する必要があるすべての要素を配置し、結合で i を使用して 1 つのステートメントで削除を行うことです。

于 2013-11-06T11:34:01.740 に答える