ALTER PROCEDURE ReadNews
@CategoryID INT,
@Culture TINYINT = NULL,
@StartDate DATETIME = NULL,
@EndDate DATETIME = NULL,
@Start BIGINT, -- for paging
@Count BIGINT -- for paging
AS
BEGIN
SET NOCOUNT ON;
--ItemType for news is 0
;WITH Paging AS
(
SELECT news.ID,
news.Title,
news.Description,
news.Date,
news.Url,
news.Vote,
news.ResourceTitle,
news.UserID,
ROW_NUMBER() OVER(ORDER BY news.rank DESC) AS RowNumber, TotalCount = COUNT(*) OVER()
FROM dbo.News news
JOIN ItemCategory itemCat ON itemCat.ItemID = news.ID
WHERE itemCat.ItemType = 0 -- news item
AND itemCat.CategoryID = @CategoryID
AND (
(@StartDate IS NULL OR news.Date >= @StartDate) AND
(@EndDate IS NULL OR news.Date <= @EndDate)
)
AND news.Culture = @Culture
and news.[status] = 1
)
SELECT * FROM Paging WHERE RowNumber >= @Start AND RowNumber <= (@Start + @Count - 1)
OPTION (OPTIMIZE FOR (@CategoryID UNKNOWN, @Culture UNKNOWN))
END
这是结构News
and ItemCategory
tables:
CREATE TABLE [dbo].[News](
[ID] [bigint] NOT NULL,
[Url] [varchar](300) NULL,
[Title] [nvarchar](300) NULL,
[Description] [nvarchar](3000) NULL,
[Date] [datetime] NULL,
[Rank] [smallint] NULL,
[Vote] [smallint] NULL,
[Culture] [tinyint] NULL,
[ResourceTitle] [nvarchar](200) NULL,
[Status] [tinyint] NULL
CONSTRAINT [PK_News] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE TABLE [ItemCategory](
[ID] [bigint] IDENTITY(1,1) NOT NULL,
[ItemID] [bigint] NOT NULL,
[ItemType] [tinyint] NOT NULL,
[CategoryID] [int] NOT NULL,
CONSTRAINT [PK_ItemCategory] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
此查询读取特定类别的新闻(体育、政治……)。@Culture
参数指定新闻的语言,如0(英语)、1(法语)等。ItemCategory
表将新闻记录与一个或多个类别相关联。ItemType
列于ItemCategory
表指定了哪种类型itemID
有没有。目前,我们只有ItemType
0 表示ItemID
引用一条记录News
table.
目前,我有以下索引ItemCategory
table:
CREATE NONCLUSTERED INDEX [IX_ItemCategory_ItemType_CategoryID__ItemID] ON [ItemCategory]
(
[ItemType] ASC,
[CategoryID] ASC
)
INCLUDE ( [ItemID])
以及新闻表的以下索引(由查询分析器建议):
CREATE NONCLUSTERED INDEX [_dta_index_News_8_1734000549__K1_K7_K13_K15] ON [dbo].[News]
(
[ID] ASC,
[Date] ASC,
[Culture] ASC,
[Status] ASC
)
使用这些索引,当我执行查询时,对于某些参数,查询执行时间不到一秒,而对于其他参数(例如不同的@Culture或@CategoryID)可能最多需要2分钟!我用过OPTIMIZE FOR (@CategoryID UNKNOWN, @Culture UNKNOWN)
防止参数嗅探@CategoryID
and @Culture
参数,但似乎不适用于某些参数。
目前大约有 2,870,000 条记录News
表和 4,740,000ItemCategory
table.
现在,我非常感谢有关如何优化此查询或其索引的任何建议。
update:
execution plan:
(in this image, ItemNetwork is what I referred to as ItemCategory. they are the same)