我正在编写一个查询,以返回新闻门户主页的文章列表。 要求如下。
需要在主页上的每个类别需要按照以下标准显示5篇文章。
每个类别都需要有一篇文章作为该类别的主要新闻,其次是4篇当时最受欢迎的新闻。 如果没有关于类别集的第一个新闻,则显示5个最受欢迎的内容。
我写了一个SQL函数,它有CategoryID参数和另一个调用该函数N Times的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 :(得分:0)
一个潜在的改进是将Fn_FetchHomepageCategory函数中的两个SELECT子句合并为一个单个查询,方法是添加一个新的Coefficient参数:
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的帖子时,它才能正常工作。