2012-03-22 5 views
1

J'ai une table qui contient à la fois mes messages et mes commentaires. Nous allons seulement un commentaire profond, pas de commentaires sur les commentaires. À l'heure actuelle, nous effectuons une requête ajax pour les messages, puis saisissons les commentaires dans une autre requête, en utilisant les identifiants des messages parents pour récupérer les commentaires enfants appropriés.Système de commentaires SQL Server 2008 - Quoi de plus efficace?

Ce que je veux faire est de consolider cela dans le système de requête unique le plus efficace possible.

Cela me laisse soit en utilisant CROSS APPLY ou UNION, si je ne me trompe pas, mais il y a des mises en garde:

  • Nous voulons sélectionner les 10 meilleurs messages, et le top 2 commentaires pour chaque
  • Les postes doivent être énumérés dans l'ordre décroissant
  • commentaires doivent être énumérés dans l'ordre croissant

Voici un exemple de notre cabot louer des requêtes pour les messages et commentaires:

Messages:

SELECT TOP 10 ForumPostID, ForumID, ContentText, Hidden, S.Firstname, S.Lastname, 
CONVERT(VARCHAR(30),DATEADD(hh,CASE 
     WHEN DD.StartDate IS NOT NULL THEN 5 ELSE 6 
     END, 
FP.PostDate),126)+'Z' AS PostDate, 
PostDate AS UglyTime, TopPostID, 
(SELECT COUNT(*) FROM Admin.dbo.ForumPosts WHERE TopPostID = FP.ForumPostID) AS  
'CommentCount', 
(SELECT COUNT(*) FROM Admin.dbo.ForumLikes WHERE ForumPostID = FP.ForumPostID) AS 'Likes',  
CASE (SELECT COUNT(*) FROM Admin.dbo.ForumLikes WHERE ForumPostID = FP.ForumPostID AND  
     Authuser = FP.Authuser) WHEN 0 THEN 'Like' ELSE 'You liked this.' END AS 'LikeText' 
FROM Admin.dbo.ForumPosts FP 
INNER JOIN Student.dbo.Student S 
     ON S.StudentUID = FP.Authuser 
INNER JOIN Admin.dbo.DayLightSavingsDates DD 
     ON FP.PostDate BETWEEN DD.StartDate AND DD.EndDate 
WHERE FP.ForumPostID NOT IN (SELECT Top 0 ForumPostID FROM Admin.dbo.ForumPosts FP2 ORDER BY 
FP2.ForumPostID DESC) 
AND FP.Hidden = 'N' AND FP.ContentText <> '' 
AND FP.PostType = 'post' 
ORDER BY FP.PostDate DESC 

Commentaires:

SELECT TOP 50 ForumPostID, ForumID, ContentText, Hidden, S.Firstname, S.Lastname, 
CONVERT(VARCHAR(30),DATEADD(hh,CASE 
     WHEN DD.StartDate IS NOT NULL THEN 5 ELSE 6 END, 
FP.PostDate),126)+'Z' AS PostDate, 
PostDate AS UglyTime, TopPostID, 
(SELECT COUNT(*) FROM Admin.dbo.ForumPosts WHERE TopPostID = FP.ForumPostID) AS  
     'CommentCount', 
(SELECT COUNT(*) FROM Admin.dbo.ForumLikes WHERE ForumPostID = FP.ForumPostID) AS 'Likes', 
CASE (SELECT COUNT(*) FROM Admin.dbo.ForumLikes WHERE ForumPostID = FP.ForumPostID AND 
    Authuser = FP.Authuser) WHEN 0 THEN 'Like' ELSE 'You liked this.' END AS 'LikeText' 
FROM Admin.dbo.ForumPosts FP 
INNER JOIN Student .dbo.Student S 
ON S.StudentUID = FP.Authuser 
INNER JOIN Admin.dbo.DayLightSavingsDates DD ON FP.PostDate BETWEEN DD.StartDate AND DD.EndDate 
WHERE FP.ForumPostID NOT IN 
    (SELECT Top 0 ForumPostID FROM Admin.dbo.ForumPosts FP2 ORDER BY FP2.ForumPostID DESC) 
AND FP.ForumPostID IN 
    (SELECT Top 2 ForumPostID FROM Admin.dbo.ForumPosts FP3 WHERE FP3.TopPostID = FP.TopPostID 
     ORDER BY FP3.PostDate DESC) 
AND FP.Hidden = 'N' 
AND FP.ContentText <> '' 
AND FP.PostType = 'comment' 
AND FP.TopPostID IN (373, 371, 370, 369, 368, 367, 366, 365, 364, 363) 
ORDER BY FP.ForumPostID ASC 
+1

-1: Formatez votre code de manière lisible! – Akhil

+0

Désolé, il soumis avant que je sois prêt pour cela, même si je n'ai pas cliqué sur le bouton. Ca devrait être un peu mieux maintenant. – ilikenwf

+0

* Le bouton lui-même cliqué! Je le jure! * –

Répondre

0

Le conseil le plus important qui peut être donné ici est que vous devez examiner le plan d'exécution. Je ne connais pas un moyen de contourner cela. La requête est trop complexe pour donner des conseils spécifiques. Une chose cependant: Vous avez beaucoup d'expressions comme "(COUNT COUNT (*) FROM Admin.dbo.ForumPosts WHERE TopPostID = FP.ForumPostID)". L'optimiseur de requête SQL Server a des problèmes d'utilisation de ces expressions dans les calculs. Il échoue parfois à les convertir en une jointure normale, ce qui empêche de nombreuses optimisations. Vous pourriez vouloir les convertir en jointures. Les clauses IN sont cependant sûres pour autant que je sache.

+0

Je voudrais garder ces comptes comme un champ dans la table et maitnain eux via des déclencheurs. Le compte est une opération très lourde. Vous tuez totalement le besoin lorsque vous maintenez les comptes. – TomTom