Je suppose qu'il s'agit d'un SP assez courant dans les réseaux sociaux et les sites Web de type communautaire. J'ai ce SP qui renvoie tous les amis d'un utilisateur sur leur page d'amis par ceux actuellement en ligne, puis par ordre alphabétique. Ça prend beaucoup de temps à charger et je cherche à l'accélérer. Je me souviens avoir lu quelque part sur SO que briser plusieurs jointures en ensembles de résultats plus petits pourrait l'accélérer. Je n'ai pas encore essayé, mais je suis curieux de voir quelles autres recommandations pourraient avoir sur cette procédure.Optimisation de cette requête. Pertinent pour les administrateurs de bases de données travaillant sur un site Web de type réseau social/communautaire
DECLARE @userID INT -- This variable is parsed in
DECLARE @lastActivityMinutes INT
SET @lastActivitytMinutes = '15'
SELECT
Active = CASE WHEN DATEDIFF("n", b.LastActivityDate ,GETDATE()) < @lastActivityMinutes THEN 1 ELSE 0 END,
a.DisplayName, a.ImageFile, a.UserId, b.LastActivityDate
FROM
Profile AS a
INNER JOIN aspnet_Users as b on b.userId = a.UserId
LEFT JOIN Friend AS x ON x.UserID = a.UserID
LEFT JOIN Friend AS z ON z.FriendID = a.UserID
WHERE ((x.FriendId = @userID AND x.status = 1) -- Status = 1 means friendship accepted
OR (z.UserID = @userID AND z.Status = 1))
GROUP BY a.userID, a.DisplayName, a.ImageFile, a.UserId, b.LastActivityDate
ORDER BY Active DESC, DisplayName ASC
Je ne suis pas sûr de savoir comment clip dans mon plan d'exécution, mais le principal goulot de la bouteille semble se produire sur un MERGE JOIN (jointure externe droite) qui me coûte 29%. À différents stades, le parallélisme coûte également 9%, 6%, 5% et 9% pour un total de 29%. Mes réflexions initiales sont de retourner d'abord les résultats JOINTED des tables Profile et aspnet avec un CTE, puis de faire des JOINT LEFT à la table des amis.
Oui, cela nous amène à mes premiers problèmes. Parfois, un utilisateur fait ou reçoit seulement 1 demande d'ami. Cela signifie que l'ID peut exister dans la colonne UserID ou FriendID de la table Friend. Faire des INNER JOIN comme celui que vous avez déclaré ne lui rendra pas son amitié. En utilisant votre script, ma sélection de retour est passée de 395 (mine) à 362 lignes. – super9
@Nai: est-ce pour la nouvelle requête avec 'UNION ALL'? – Quassnoi
Ceci est pour l'ancien. Avec celui-ci, il ne retourne aucune ligne. J'essaie actuellement de déterminer pourquoi – super9