インデックスが破損しているように見えるものがありますか?
これが何が起こっているかです。私は 2 つのテーブル関数を持っています。1 つ目はケースのセットで、2 つ目は日付のセットです。これらの 2 つのセットには、1 (ケース) 対 0 または 1 (認識日) の関係があります。通常、私はそれらを次のようにクエリします。
SELECT c.CaseID, a.AwareDate
FROM Cases(@date) AS c
LEFT JOIN AwareDates(@date) AS a ON c.CaseID = a.CaseID;
問題は、一致する AwareDates のすべての行が JOIN されているように見えないことです。結合ヒントを追加すると、それらは実行されます。いう;
SELECT c.CaseID, a.AwareDate
FROM Cases(@date) AS c
LEFT MERGE JOIN AwareDates(@date) AS a ON c.CaseID = a.CaseID;
クエリ プランから気付いたのは、結合ヒントを追加すると、結合の前に AwareDate データの一種が追加されることです。これは、他の方法では存在しません。また、クエリ プランナーは、ヒントがない場合、結合を RIGHT OUTER JOIN に切り替えます。もちろん、ヒントが存在する場合は LEFT JOIN を保持します。
エラーが検出されずに次のことを行いました。
DBCC UPDATEUSAGE (0) WITH INFO_MESSAGES, COUNT_ROWS;
EXECUTE sp_updatestats 'resample';
DBCC CHECKDB (0) WITH ALL_ERRORMSGS, EXTENDED_LOGICAL_CHECKS;
私は困惑しています...何かアイデアはありますか?
UDF の定義は次のとおりです。
ALTER FUNCTION dbo.Cases( @day date ) RETURNS TABLE
WITH SCHEMABINDING
AS RETURN (
SELECT
CaseID -- other 42 columns ommitted
FROM (
SELECT
ROW_NUMBER() OVER (PARTITION BY CaseID ORDER BY UpdateDate DESC, UpdateNumber DESC) AS RecordAge,
CaseID,
Action
FROM
dbo.CaseAudit
WHERE
convert(date,UpdateDate) <= @day
) AS History
WHERE
RecordAge = 1 -- only the most current record version
AND isnull(Action,'') != N'DEL' -- only include cases that have not been deleted
)
ALTER FUNCTION dbo.AwareDates( @day date ) RETURNS TABLE
WITH SCHEMABINDING
AS RETURN (
WITH
History AS (
SELECT row_number() OVER (PARTITION BY CaseID, ContactID ORDER BY UpdateDate DESC, UpdateNumber DESC) AS RecordAge,
CaseID, InfoReceived, ReceiveDate, ResetClock, Action
FROM dbo.ContactLogAudit WITH (NOLOCK)
WHERE convert(date,UpdateDate) <= @day
),
Notes AS (
SELECT
CaseID,
convert(date,ReceiveDate,112) AS ReceiveDate,
ResetClock
FROM History
WHERE RecordAge = 1 -- only the most current record version
AND isnull(Action,'') != N'DEL' -- only include notes that have not been deleted
AND InfoReceived = N'Y' -- only include notes that have Info Rec'd checked
AND len(ReceiveDate) = 8 AND isnumeric(ReceiveDate) = 1 AND isdate(ReceiveDate) = 1 -- only include those with a valid aware date
),
Initials AS (
SELECT CaseID, min(ReceiveDate) AS ReceiveDate
FROM Notes
GROUP BY CaseID
),
Resets AS (
SELECT CaseID, max(ReceiveDate) AS ReceiveDate
FROM Notes
WHERE ResetClock = N'Y'
GROUP BY CaseID
)
SELECT
i.CaseID AS CaseID,
i.ReceiveDate AS InitialAwareDate, -- the oldest valid aware date value (must have AE Info Reveived checked and a received date)
coalesce(r.ReceiveDate,i.ReceiveDate) AS AwareDate -- either the newest valid aware date value with the Reset Clock checked, otherwise the initial aware date value
FROM Initials AS i
LEFT JOIN Resets AS r
ON i.CaseID = r.CaseID
);
さらに、「WITH (NOLOCK)」テーブル ヒントを削除すると、正しい結果が得られることがわかりました。また、結合ヒントを AwareDates UTF に追加するか、イニシャルとリセットの間の LEFT JOIN 関係に COLLATE Latin1_General_BIN を追加する場合。
クエリ プランの行数 -- 結合ヒントなし (破損)
- ケース { 実績: 25,891、推定: 19,071.9 }
- AwareDates { 実際: 24,693、推定: 1,463.09 }
- イニシャル { 実際: 24,693、推定: 1,463.09 }
- 残り { 実際: 985、推定: 33.2671 }
- AwareDates は、結合された結果セットの 8,108 行の Cases と一致します
クエリ プランの行数 -- 結合ヒントあり (動作中)
- ケース { 実績: 25,891、推定: 19,071.9 }
- AwareDates { 実際: 24,673、推定: 1,837.67 }
- イニシャル { 実際: 24,673、推定: 1,837.67 }
- 残り { 実際: 982、推定: 42.6238 }
- AwareDates は、結合された結果セットの 24,673 行の Cases と一致します
問題の範囲をさらに絞り込みました。できます;
SELECT * FROM AwareDate(@date);
と
SELECT * FROM AwareDate(@date) ORDER BY CaseID;
行数が異なります。