ここではC#プログラマーです。私はパフォーマンスの向上と効率的な実行を可能にする従来のアプリケーションのうちの1つで、長いSQL Serverプロシージャを編集するように指示されています。私のルートが手近なシナリオのために取るのが最善であるなら、私はいくつかの確認に感謝します。SQL Server:クエリを最適化する
SCENARIO
それが原因の元デザイナーによる両方のコードとDB賢明な設計に異例の一つです。検索グリッドでは、ユーザが選択したオプションと文字列/単語 "Warranty"の連結値とtbl.warranty.warrantyId
値自体に基づいて、tbl.docs
に "保証書"が生成されているかどうかを確認する必要があります。
この 'Warranty'の値+ tbl.warranty.warrantyId
は、tbl.docs.name
という列の値と同じですが、残念ながら2つのテーブルを結合/リンクする唯一の方法です。
保証ドキュメントは、保証ごとに複数回生成することができます。
パラメータ@IsGenerated
は、エンドユーザがフィルタリングを行うかどうかを選択するユーザオプションです。ここで
は、説明のためのいくつかの人口のデータがあります:
tbl.warranty
:
| warrantyId | name | createdDate |
|------------|-------------|-------------------------|
| 456 | Warranty 1 | 2002-04-01 12:14:53.330 |
| 1000 | Warranty 2 | 2002-04-01 12:14:53.327 |
| 1701 | Warranty 3 | 2002-04-01 12:14:53.333 |
| 2456 | Warranty 4 | 2002-04-01 12:14:53.327 |
| 3556 | Warranty 5 | 2002-04-01 12:14:53.330 |
tbl.docs
:
| docId | name | createdDate |
|------------|--------------|-------------------------|
| 1 | Warranty1000 | 2006-11-25 13:33:31.093 |
| 2 | Warranty456 | 2015-02-11 13:33:31.100 |
| 3 | Warranty1000 | 2012-05-17 13:33:31.097 |
| 4 | Warranty1000 | 2017-01-11 13:33:31.097 |
| 5 | Warranty1701 | 2017-03-14 13:33:31.100 |
| 6 | Warranty456 | 2017-03-15 13:33:31.100 |
だから、あなたが見ることができます:
- warrantyId千ヘクタールwarrantyId 456はwarrantyIds 3556および2456で二回
- 保証は、全くそうで...
目的のアクション(複数可)/結果を(生成されていない生成された3回
ユーザーはフィルタオプションを選択しないように選択することができます。[生成されたすべての保証記録と時間(tbl.docs.createdDate)を表示する必要がありますが、nullのtbl.docs.createdDate(generateddateもしあなたがそれを生成するよう要求されていなければ)、またはmaに基づく最新のレコードX tbl.docs.createdDateそれが持っている場合(generatedDate)]ユーザが[私はドキュメントは、レコードに基づいて生成されているすべての保証レコードを表示する必要がある、ドキュメントがのために生成されている保証にフィルタリングすることができ
| warrantyId | name | generatedDate |
|------------|--------------|-------------------------|
| 456 | Warranty 1 | 2017-03-15 13:33:31.100 |
| 1000 | Warranty 2 | 2017-01-11 13:33:31.097 |
| 1701 | Warranty 3 | 2017-03-14 13:33:31.100 |
| 2456 | Warranty 4 | NULL |
| 3556 | Warranty 5 | NULL |
文字列/単語 "Warranty"と保証IDはdocs.name値と等しくなります。複数のドキュメントを持っている保証は、生成され、私は最新の時間を必要とするユーザーは、[私は避難所」すべての保証レコードを表示する必要がある、ドキュメントがのために生成されていないことを保証にフィルタリングすることができ
| warrantyId | name | generatedDate |
|------------|--------------|-------------------------|
| 456 | Warranty 1 | 2017-03-15 13:33:31.100 |
| 1000 | Warranty 2 | 2017-01-11 13:33:31.097 |
| 1701 | Warranty 3 | 2017-03-14 13:33:31.100 |
]レコードを生成しました文字列/単語「Warranty」と保証書と同等のドキュメントに基づいて、doc生成レコードがありました。名前] | warrantyId | name | generatedDate |
|------------|--------------|-------------------------|
| 2456 | Warranty 4 | NULL |
| 3556 | Warranty 5 | NULL |
これは私のスタブです。私は、テーブルテーブルに基づいて一時テーブルを作成し、私のクエリでそれを使用して効率性のための最善のルートではなく、すでに何がこのクエリをボグしていない考え出した。
IF OBJECT_ID('tempdb..#tmpDocs') IS NOT NULL
DROP TABLE #tmpDocs
GO
CREATE TABLE #tmpDocs
(
createdDate datetime not null,
name varchar(30) not null
)
INSERT INTO #tmpDocs (createdDate, name)
SELECT createdDate, name
FROM docs
DECLARE @IsGenerated BIT
SET @IsGenerated = 0
SELECT
w.warrantyId,
w.name,
(SELECT TOP 1 d.createdDate
FROM #tmpDocs d
WHERE d.name = CONCAT('Warranty', w.warrantyId)
ORDER BY d.createdDate DESC) AS [generatedDate]
FROM
warranty w
WHERE
(@IsGenerated IS NULL OR @IsGenerated = 0
OR EXISTS (SELECT *
FROM #tmpDocs d
WHERE d.name = CONCAT('Warranty', w.warrantyId)))
AND (@IsGenerated IS NULL OR @IsGenerated = 1 OR
NOT EXISTS (SELECT *
FROM #tmpDocs d
WHERE d.name = CONCAT('Warranty', w.warrantyId)
)
)
)
EDITED - ATTEMPT#2
select
w.warrantyId,
w.name,
d.createdDate as [generatedDate]
from warranty w
left join #tmpDocs d
on d.name = concat('Warranty', w.warrantyId)
AND d.createdDate = (SELECT top 1 d.createdDate
FROM #tmpDocs d
WHERE d.name = CONCAT('Warranty', w.warrantyId)
ORDER BY d.createdDate desc)
WHERE
(@IsGenerated IS NULL OR @IsGenerated = 0
OR EXISTS (SELECT *
FROM #tmpDocs d
WHERE d.name = CONCAT('Warranty', w.warrantyId))
)
AND (@IsGenerated IS NULL OR @IsGenerated = 1
OR NOT EXISTS (SELECT *
FROM #tmpDocs d
WHERE d.name = CONCAT('Warranty', w.warrantyId)
)
)
group by w.warrantyId, d.createdDate, w.name
実行時間は、私の小さなデータセット私が働いているので、私は推測している、しかし同じです。
(5行が影響を受けます)
SQL Server実行時間: CPU時間= 0 ms、経過時間= 0 ms。
(5行(複数可)の影響を受ける)
SQL Serverの実行時間: CPU時間= 0秒、経過時間= 0秒。
このようなことを読んでくれてありがとうございます。代替ルートがある場合(これは、私が編集するprocの単純な側面の1つで、CTEを使用しないためです)、すべてをリファクタリングする時間がありませんその時に)、私はそれを聞いて非常に開いているだろう。この手続きを実行することで、手間がかからないようにすることはできません。
私は非常に感謝しています。私はテーブルの構造を編集することはできません。保証文書が生成されているだけではありません。保存されたprocをすべてフィルタリングし、アプリケーション側でデザイン/ワークフローを編集すると、割り当てられた時間このプロジェクトに与えられたものです。私は基本的にその場所の構造で作業することを余儀なくされています。 – theoryTim
あなたが働いているSPの数はわかりませんが、上記のクエリはあなたが探している結果を得るはずです。 あなたの検索結果に最新のドキュメントだけが必要だったのですか、またはドキュメントごとに1つの保証が必要でしたか? – Vee
また、テーブルのインデックスを変更することは可能ですか?元の質問には言及していませんでした。通常、最適なインデックスを作成するには、良いインデックスと悪いインデックスが最適です。 – Vee