web-dev-qa-db-ja.com

クエリを最適化してスピードアップするには

以下のクエリは決して完了せず、14時間以上実行されます。

SELECT 
U.Age, U.CreationDate, U.DisplayName, 
P.AcceptedAnswerId, P.ClosedDate, p .Title, P.ViewCount,
C.CreationDate,C.Score ,C.UserId
FROM dbo.Users As U
LEFT JOIN dbo.Posts As P on U.id = P.id
LEFT JOIN dbo.Comments As C on U.id =C.id
WHERE
(
U.Location = 'India'
OR U.Location ='United Kingdom'
)
AND U.LastAccessDate>= '04/02/2018'
AND U.LastAccessDate< '06/02/2018'
AND P.LastActivityDate>= '04/02/2018'
AND P.LastActivityDate< '06/02/2018'
AND U.LastAccessDate>= '04/02/2018'
AND U.LastAccessDate< '06/02/2018'
AND U.Age>10
AND U.Age is NOT NULL

どうすれば改善してスピードアップできますか?

1
BeginnerDBA

私が目にする最大の問題はあなたの参加です。ユーザーの「ID」、投稿とコメントの「ID」に参加しています。これは基本的に、Usersのすべてのレコードを取得し、それをPostsのすべてのレコードに結合してから、Commentsのすべてのレコードに結合します。

UserIDが投稿とコメントの外部キーとして存在すると想定すると、以下のコードが機能するはずです。そうでない場合は、JOINステートメントの正しい外部キーを決定する必要があります。

SELECT 
    U.Age, 
    U.CreationDate, 
    U.DisplayName,
    P.AcceptedAnswerId, 
    P.ClosedDate, 
    P.Title, 
    P.ViewCount,
    C.CreationDate,
    C.Score,
    C.UserId
FROM 
    dbo.Users AS U
    LEFT OUTER JOIN dbo.Posts AS P 
        ON U.UserID = P.UserID
    LEFT OUTER JOIN dbo.Comments AS C 
        ON U.UserID = C.UserID
WHERE
    U.Location IN ('India','United Kingdom')
    AND U.LastAccessDate>= '04/02/2018'
    AND U.LastAccessDate< '06/02/2018'
    AND P.LastActivityDate>= '04/02/2018'
    AND P.LastActivityDate< '06/02/2018'
    AND U.Age>10

Location ORステートメントをINに置き換えました。

重複するU.LastAccessDate条件を削除しました。

不要なU.Age IS NOT NULL状態を削除しました。

このクエリの実行速度が遅い場合。次に考えられるのは、Users.LastAccessDateやPosts.LastActivityDateのインデックスが見つからないことです。

1
MrPshaw

ここであなたがする必要があること:

1)#Tempテーブルを使用する
2)パーツのクエリを分解し、段階的にデータを取得します
3)WHEREまたはjoin ON句で使用する列にインデックスが付けられていることを確認してください

一時テーブル-以下の列のデータ型は一例にすぎません。テーブルの列のデータ型と完全に一致するデータ型を使用してください

 create table #UserInfo(
 tID int primary key clustered、
 
 tAge tinyint、
 tCreationDate datetime、
 tDisplayName varchar( 50)、
 
 tAcceptedAnswerID int、
 tClosedDate datetime、
 tTitle varchar(50)、
 tViewCount int、
 
 tCreationDate datetime、
 tScore int、
 tUserID int)

ユーザー情報を取得します-LocationAgeLastAccessDate列がUsersテーブルでインデックス付けされていることを確認します

-ユーザー情報を取得
#UserInfoに挿入(tID、tAge、tCreationDate、tDisplayDate)
 select 
 U.ID、
 U. Age、
 U.CreationDate、
 U.DisplayName、
 from dbo.Users As U 
 where(U.Location = 'India' OR U.Location = 'United Kingdom')
およびU.Age> 10 
およびU.AgeがNOT NULL 
およびU.LastAccessDate> = '04 /02/2018'
およびU.LastAccessDate 
 

-投稿情報の取得-投稿テーブルのID、LastActivityDate列がインデックス化されていることを確認します
-投稿情報を取得します。 。] tViewCount = P.ViewCount from #UserInfo join dbo.Posts As P on tID = p.id and P.LastActivityDate> = '04 /02/2018' およびP.LastActivityDate <'06 /02/2018'
-コメント情報を取得-コメントテーブルのID列にインデックスが作成されていることを確認します
-コメント情報を取得します 更新#UserInfo セットtCreationDate = C.CreationDate、 tScore = C.Score、 tUserID = C.UserId #UserInfo から U.id = C.id のdbo.Comments As Cに参加
-データの表示 選択 tAge [年齢]、 tCreationDate [CreationDate]、 tDisplayName [DisplayName]、 tAcceptedAnswerID [AcceptedAnswerID], tClosedDate [ClosedDate], tTitle [Title], tViewCount [ViewCount], tCreationDate [CreationDate], tScore [Score], tUserID [UserID]

#UserInfoから

1
Aleksey Vitsko