2017-12-11 22 views
0

뉴스 포털 홈페이지에 대한 기사 목록을 반환하는 쿼리를 작성 중입니다. 요구 사항은 다음과 같습니다. 홈페이지에 있어야다음 SQL 쿼리를 작성하는 더 효과적인 방법

각 범주 기준에 따라 5 개 기사를 표시 할 필요가있다.

각 카테고리는 당분간에서 4 가장 인기있는 뉴스 다음에 범주에 대한 주요 소식 하나 개의 기사를 가질 필요가있다. 카테고리 세트에 대한 첫 번째 뉴스가 없다면, 가장 인기있는 insted를 5 개 표시하십시오.

나는 카테고리 ID 매개 변수 및 그 기능 N 시간을 호출하는 다른 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 

저장 프로 시저 : 나는 하나의 선택을 가지고 기능을 수정하기 위해 노력하고 Order BY IsFirstCategory DESC을 포함하지만, 쿼리가 다음 훨씬 느린 실행

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 

.

답변

0

하나 개의 잠재적 인 개선은 새로운 만들어 낸 계수 매개 변수를 추가하여 하나 개의 쿼리로 Fn_FetchHomepageCategory 기능에 두 개의 SELECT 절을 병합 할 것입니다 : 당신은 또 다른 큰 번호 1000000을 대체 할 수

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 

. 유일한 포인트는 IsCategoryFirst = 1 인 게시물에 가능한 최고 수준의 공동 효율성 점수를 할당하는 것입니다. IsCategoryFirst = 1 인 게시물이 하나 뿐인 경우에만 작동합니다.

+0

이것은 코드에서 깔끔한 변화입니다. 그러나 그것은 나의 쿼리를 3 번 ​​늦추었다. – Robert