言い換えれば、下の画像のsort
演算子を取り除くにはどうすればよいですか?
上の画像 次の2つの選択の実行プランを一緒に示します :
SELECT TOP 1 so.OrgType,
ch.Status,
rcs.DBSstatusDescription,
cid.ApplicationId
FROM tbl_application_crb_initialData cid
INNER JOIN tbl_season_organisationId so
ON cid.OrganisationId = so.OrgId
LEFT JOIN tbl_crbHistory ch
ON cid.ClientReference = ch.ClientReference
LEFT JOIN ref_crbStatus rcs
ON ch.Status = rcs.statusId
ORDER BY cid.DateAdded DESC, ch.DateAdded DESC
SELECT TOP 1 so.OrgType,
ch.Status,
rcs.DBSstatusDescription,
cid.ApplicationId
FROM tbl_application_crb_initialData cid
INNER JOIN tbl_season_organisationId so
ON cid.OrganisationId = so.OrgId
LEFT JOIN tbl_crbHistory ch
ON cid.ClientReference = ch.ClientReference
LEFT JOIN ref_crbStatus rcs
ON ch.Status = rcs.statusId
ORDER BY cid.DateAdded DESC--, ch.DateAdded DESC
唯一の違いは、2番目のクエリでは、順番に1つの列しかないことです。
top 1
を使用しているので、違いはありますか?
必要な情報はすべて、インデックスとテーブルの定義にあると思います クエリプランで確認できます 。
それを取り除くために他に役立つものがある場合は、sort
にお知らせください。明日、可能な限りの情報をすべて投稿します。
あなたの質問には多くの詳細がありませんが、私は同様のものを再現できます。
CREATE TABLE T1(X INT PRIMARY KEY, Y INT INDEX IX)
CREATE TABLE T2(X INT, Y INT , PRIMARY KEY(X, Y))
INSERT INTO T2
OUTPUT INSERTED.* INTO T1
SELECT TOP 1000000 ROW_NUMBER() OVER (ORDER BY @@SPID), ROW_NUMBER() OVER (ORDER BY @@SPID)
FROM sys.all_objects o1, sys.all_objects o2;
SELECT TOP 1 T1.Y AS T1Y, T2.Y AS T2Y
FROM T1 JOIN T2 ON T1.X = T2.X
ORDER BY T1.Y;
SELECT TOP 1 T1.Y AS T1Y, T2.Y AS T2Y
FROM T1 JOIN T2 ON T1.X = T2.X
ORDER BY T1.Y, T2.Y
WITH T AS
(
SELECT TOP 1 WITH TIES T1.Y AS T1Y, T2.Y AS T2Y
FROM T1 JOIN T2 ON T1.X = T2.X
ORDER BY T1.Y
)
SELECT TOP 1 *
FROM T
ORDER BY T2Y
クエリ1は、インデックスからTOP 1
を目的の並べ替え順序で取得し、その行の他のテーブルで必要な結合を実行します。結合が成功した場合、そこで停止します。それ以外の場合は、行が一致するか行がなくなる行が見つかるまで、インデックス順に次の行を試行します。
Query 2新しい並べ替え列を追加すると、TOP 1
値とSQL Serverに関連付けられた複数の一致が存在する可能性があるため、このプランは無効になりますロット全体に参加することを決定し、それからTOP 1
を取得します。
Query 3これにより、SQL Serverは最初の戦略を忠実に守り、同じ値に関連付けられているすべての行に対してTOP 1 Sort
を実行します。最初のソートキー。
私の例のデータの場合、クエリ3はクエリ2よりもうまく機能しますが、最初のソートキーの値に関連付けられた多くの重複がある場合、走行距離は異なる場合があります。
あなたはこの書き直しを試して、それがどれほどの運賃かを見ることができます
WITH T
AS (SELECT TOP 1 WITH TIES so.OrgType,
ch.Status,
rcs.DBSstatusDescription,
cid.ApplicationId,
ch.DateAdded AS chDateAdded
FROM tbl_application_crb_initialData cid
INNER JOIN tbl_season_organisationId so
ON cid.OrganisationId = so.OrgId
LEFT JOIN tbl_crbHistory ch
ON cid.ClientReference = ch.ClientReference
LEFT JOIN ref_crbStatus rcs
ON ch.Status = rcs.statusId
ORDER BY cid.DateAdded DESC)
SELECT TOP 1 OrgType,
Status,
DBSstatusDescription,
ApplicationId
FROM T
ORDER BY chDateAdded DESC