2017-12-11 11 views
0

私はニュースポータルホームページの記事リストを返すためのクエリを書いています。 要件は次のとおりです。次のSQLクエリを書くより効果的な方法

ホームページに掲載する必要がある各カテゴリは、以下の基準で5つの記事を表示する必要があります。

各カテゴリには、そのカテゴリの主なニュースである記事が1つ必要です。その後、最も人気のあるニュースは4つあります。 カテゴリーセットの最初のニュースがない場合、最も人気のある5つのインスタントを表示します。

私は、CategoryIDパラメータとその関数N Timesを呼び出す別のSQLプロシージャを持つSQL関数を記述しました。

このクエリを書くより効率的な方法はありますか?

機能

CREATE FUNCTION [dbo].[Fn_FetchHomepageCategory] 
( 
    -- Add the parameters for the function here 
    @categoryId int 

) 
RETURNS @ArticlesToReturn TABLE 
         (Id int, 
         Title nvarchar(500), 
         Slug nvarchar(500), 
         Summary nvarchar(1500), 
         IsCategoryFirst bit, 
         RootCategoryId int, 
         RootCategory nvarchar(500), 
         OldFacebookCommentsUrl nvarchar(500), 
         Icon nvarchar(500), 
         TopicName nvarchar(500), 
         MainArticlePhoto nvarchar(500), 
         FrontPagePhoto nvarchar(500), 
         PublishDate datetime 

        ) 
AS 
BEGIN 


    -- select category first news if any 
    INSERT INTO @ArticlesToReturn 
    SELECT TOP 1 
    ART.Id, ART.Title, ART.InitialTitle, ART.Summary,ART.IsCategoryFirst, 
    ART.RootCategoryId, CAT.Name, ART.OldFacebookCommentsUrl, ICO.CssClass, 
    ART.TopicName, ART.MainArticlePhoto, ART.FrontPagePhoto, ART.PublishDate 
    FROM Articles ART WITH (NOLOCK) 
    INNER JOIN ArticleViewCountSum AVS WITH (NOLOCK) ON AVS.ArticleId = ART.Id 
    INNER JOIN Categories CAT WITH (NOLOCK) ON CAT.Id = ART.RootCategoryId 
    LEFT JOIN ArticleIcons ICO WITH (NOLOCK) ON ICO.Id = ART.IconId 
    WHERE ART.RootCategoryId = @categoryId 
    AND ART.PublishDate < GETDATE() 
    AND ART.Active = 1 
    AND IsCategoryFirst = 1 

    -- select 5 most popular by coefficient 
    INSERT INTO @ArticlesToReturn 
    SELECT TOP 5 
    ART.Id, ART.Title, ART.InitialTitle, ART.Summary,ART.IsCategoryFirst, 
    ART.RootCategoryId, CAT.Name, ART.OldFacebookCommentsUrl, ICO.CssClass, 
    ART.TopicName, ART.MainArticlePhoto, ART.FrontPagePhoto, ART.PublishDate 
    FROM Articles ART WITH (NOLOCK) 
    INNER JOIN ArticleViewCountSum AVS WITH (NOLOCK) ON AVS.ArticleId = ART.Id 
    INNER JOIN Categories CAT WITH (NOLOCK) ON CAT.Id = ART.RootCategoryId 
    LEFT JOIN ArticleIcons ICO WITH (NOLOCK) ON ICO.Id = ART.IconId 
    WHERE ART.RootCategoryId = @categoryId 
    AND ART.PublishDate < GETDATE() 
    AND ART.Active = 1 

    ORDER BY ART.Coefficient DESC 


    RETURN 

END 

ストアドプロシージャの

CREATE PROCEDURE [dbo].[Fetch_HomePageArticles] 

AS 
BEGIN 
    -- SET NOCOUNT ON added to prevent extra result sets from 
    -- interfering with SELECT statements. 
    SET NOCOUNT ON; 
    DECLARE @dateNow datetime = GETDATE(); 

    -- first main news 
    SELECT TOP 1 * FROM Articles 
    WHERE IsFirst = 1 AND PublishDate < @dateNow 


    --TODO: featured 
    SELECT TOP 10 * From Featured 
    WHERE PublishDate < @dateNow AND Active = 1 
    ORDER BY PublishDate DESC 


    SELECT TOP 5 * FROM Fn_FetchHomepageCategory(3) 
    SELECT TOP 5 * FROM Fn_FetchHomepageCategory(150) 
    SELECT TOP 5 * FROM Fn_FetchHomepageCategory(1523) 
    SELECT TOP 5 * FROM Fn_FetchHomepageCategory(1509) 
    SELECT TOP 5 * FROM Fn_FetchHomepageCategory(1569) 
    SELECT TOP 5 * FROM Fn_FetchHomepageCategory(1545) 
    SELECT TOP 5 * FROM Fn_FetchHomepageCategory(1548) 
    SELECT TOP 5 * FROM Fn_FetchHomepageCategory(67) 

END 

私は唯一のSELECTを持っている機能を変更しようとしたOrder BY IsFirstCategory DESCが含まれますが、クエリは、はるかに遅く走りました。

答えて

0

一つの潜在的な改善は、新しい作らアップ係数パラメータを追加することにより、1つのクエリにFn_FetchHomepageCategory機能に2つのSELECT句をマージすることになります。

SELECT 
    TOP 5 ART.Id, 
    ART.Title, 
    ART.InitialTitle, 
    ART.Summary, 
    ART.IsCategoryFirst, 
    ART.RootCategoryId, 
    CAT.Name, 
    ART.OldFacebookCommentsUrl, 
    ICO.CssClass, 
    ART.TopicName, 
    ART.MainArticlePhoto, 
    ART.FrontPagePhoto, 
    ART.PublishDate 
FROM 
    Articles ART WITH (NOLOCK) 
    INNER JOIN ArticleViewCountSum AVS WITH (NOLOCK) ON AVS.ArticleId = ART.Id 
    INNER JOIN Categories CAT WITH (NOLOCK) ON CAT.Id = ART.RootCategoryId 
    LEFT JOIN ArticleIcons ICO WITH (NOLOCK) ON ICO.Id = ART.IconId 
WHERE 
    ART.RootCategoryId = @categoryId 
    AND ART.PublishDate < GETDATE() 
    AND ART.Active = 1 
ORDER BY 
    CASE IsCategoryFirst 
    WHEN 1 THEN 1000000 
    ELSE ART.Coefficient 
    END DESC 

あなたはもう一つの大きな数で1000000を置き換えることができます。その唯一のポイントは、IsCategoryFirst = 1のポストに可能な限り最高の効率スコアを割り当てることです。 IsCategoryFirst = 1のポストを1つしか持たない場合にのみうまくいくことに注意してください。

+0

これは、クエリが3回遅くなりました。 – Robert

関連する問題