我有商店sql
ALTER procedure [dbo].[TNNews_User_SearchBasic]
@Title nvarchar(400),
@CategoryId int,
@IsInterested int,
@IsHot int,
@IsTopCategory int,
@IsPublish int,
@PageSize int,
@PageIndex int,
@OrderBy varchar(20),
@PortalId int,
@LanguageId varchar(6)
as
DECLARE @EndTime DATETIME
DECLARE @StartTime DATETIME
SET @StartTime = GETDATE()
declare @tbCategory table(Id int)
DECLARE @StartRowIndex INT
IF @PageSize=0 SELECT @PageSize=count(*) FROM TNNews
IF(@PageIndex<0) SET @PageIndex=0
SET @StartRowIndex = @PageSize*(@PageIndex-1)+1
;WITH tmpCategory(Id, Name,ParentId,Level)
AS (
SELECT
e.Id,
e.Name,
e.ParentId,
1
FROM dbo.TNCategory AS e
WHERE
Id = @CategoryId or (@CategoryId='' and ParentId<=0)
UNION ALL
SELECT
e.Id,
e.Name,
e.ParentId,
Level + 1
FROM dbo.TNCategory AS e
JOIN tmpCategory AS d ON e.ParentId = d.Id
)
insert @tbCategory select Id from tmpCategory
;WITH tmpNews as
(
SELECT
a.Id,a.Title,a.Subject
,ROW_NUMBER() OVER (ORDER BY (Publisheddate) desc) as ThuTuBanGhi
FROM dbo.TNNews a
where 1 = 1
--and ( Title like '%'+@Title+'%')
and (@CategoryId = -1 or exists (select 0 from @tbCategory b where b.Id = a.CategoryId))
and (@IsInterested = -1 or IsIntrested = @IsInterested )
and (@IsHot = -1 or IsHot = @IsHot )
and (@IsTopCategory = -1 or IsTopCategory = @IsTopCategory )
and (@IsPublish = -1 or IsPublished = @IsPublish)
and PortalId=@PortalId
and LanguageId = @LanguageId
)
select *, (select COUNT(Id) from tmpNews) as 'TongSoBanGhi' from tmpNews
WHERE
ThuTuBanGhi BETWEEN (@StartRowIndex) AND (@StartRowIndex + @PageSize-1)
SET @EndTime = GETDATE()
PRINT 'StartTime = ' + CONVERT(VARCHAR(30),@StartTime,121)
PRINT ' EndTime = ' + CONVERT(VARCHAR(30),@EndTime,121)
PRINT ' Duration = ' + STR(DATEDIFF(MILLISECOND,@StartTime,@EndTime)) + ' millisecond'
select STR(DATEDIFF(MILLISECOND,@StartTime,@EndTime))
此商店执行后
EXEC [dbo].[TNNews_User_SearchBasic]
@Title='',
@CategoryId = '',
@IsInterested = -1,
@IsHot = -1,
@IsTopCategory = -1,
@IsPublish = -1,
@PageSize = 20,
@PageIndex = 1,
@OrderBy = '',
@PortalId = 0,
@LanguageId = N'vi-VN'
go
时间约为“200ms”。我创建了一个新的商店“TNNews_User_SearchBasic1”并进行了一些更改。
.....
--,ROW_NUMBER() OVER (ORDER BY (Publisheddate) desc) as ThuTuBanGhi
,ROW_NUMBER() OVER (ORDER BY (case when @OrderBy='VIEW_COUNT' then ViewCount else PublishedDate end) desc) as ThuTuBanGhi
.....
现在是执行此商店的时间
EXEC [dbo].[TNNews_User_SearchBasic1]
@Title='',
@CategoryId = '',
@IsInterested = -1,
@IsHot = -1,
@IsTopCategory = -1,
@IsPublish = -1,
@PageSize = 20,
@PageIndex = 1,
@OrderBy = '',
@PortalId = 0,
@LanguageId = N'vi-VN'
GO
大约900毫秒。
我不明白为什么会有变化。请帮我改进这些商店。
PS:我将示例数据库放在:http://anhquan22.tk/Portals/0/Videos/web.rar
答案 0 :(得分:0)
完成分析数据库的结构。问题的一部分隐藏在表结构中。 我为你准备了备份。在其中,我稍微修改了方案以提高性能并对表进行规范化。您可以从this link下载。
...对于你的问题,我会这样做 -
DECLARE @SQL NVARCHAR(1000)
SELECT @SQL = N'
;WITH tmpCategory (Id, Name, ParentId, [Level]) AS
(
SELECT
e.Id
, e.Name
, e.ParentId
, 1
FROM dbo.TNCategory e
WHERE Id = @CategoryId OR (@CategoryId = '''' AND ParentId <= 0)
UNION ALL
SELECT
e.Id
, e.Name
, e.ParentId
, [Level] + 1
FROM dbo.TNCategory e
JOIN tmpCategory d ON e.ParentId = d.Id
)
SELECT
a.Id
, ROW_NUMBER() OVER (ORDER BY ' +
CASE WHEN @OrderBy = 'VIEW_COUNT'
THEN 'ViewCount'
ELSE 'PublishedDate'
END +' DESC) AS ThuTuBanGhi
FROM dbo.TNNewsMain a
where PortalId = @PortalId
AND LanguageId = @LanguageId'
+ CASE WHEN @IsInterested != -1 THEN ' AND IsInterested = @IsInterested' ELSE '' END
+ CASE WHEN @IsHot != -1 THEN ' AND IsHot = @IsHot' ELSE '' END
+ CASE WHEN @IsTopCategory != -1 THEN ' AND IsTopCategory = @IsTopCategory' ELSE '' END
+ CASE WHEN @IsPublish != -1 THEN ' AND IsPublish = @IsPublish' ELSE '' END
+ CASE WHEN @CategoryId != -1 THEN '' ELSE ' AND EXISTS(SELECT 1 FROM tmpCategory b WHERE b.Id = a.CategoryId)' END
INSERT INTO @temp (Id, ThuTuBanGhi)
EXECUTE sp_executesql
@SQL
, N'@PortalId INT
, @LanguageId VARCHAR(6)
, @CategoryId INT
, @IsInterested INT
, @IsHot INT
, @IsTopCategory INT
, @IsPublish INT'
, @PortalId = @PortalId
, @LanguageId = @LanguageId
, @CategoryId = @CategoryId
, @IsInterested = @IsInterested
, @IsHot = @IsHot
, @IsTopCategory = @IsTopCategory
, @IsPublish = @IsPublish;
SELECT
d.Id
, tm.Title
, tm.[Subject]
, d.ThuTuBanGhi
, c.TongSoBanGhi
FROM (
SELECT t.Id
, t.ThuTuBanGhi
FROM @temp t
WHERE t.ThuTuBanGhi BETWEEN @StartRowIndex AND @StartRowIndex + @PageSize - 1
) d
JOIN TNNewsMain tm ON d.Id = tm.Id
CROSS JOIN (
SELECT TongSoBanGhi = (SELECT COUNT(1) FROM @temp)
) c