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
и ItemCategory
таблиц:Пожалуйста, помогите мне с этим запросом (SQL Server 2008)
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
.
В настоящее время у меня есть следующий индекс ItemCategory
таблице:
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)
, чтобы предотвратить параметр sniffing для параметров @CategoryID
и @Culture
, но, похоже, не работает для некоторых параметров.
В настоящее время насчитывается около 2,870,000 записей в таблице News
и 4,740,000 в таблице ItemCategory
.
Теперь я ценю любые советы по оптимизации этого запроса или его индексов.
обновления: План исполнения:
(в этом образе, ItemNetwork является то, что я говорил, как ItemCategory они одинаковы.)
Можете ли вы опубликовать текстовую версию плана запроса, хотя он вполне может использовать индексы, нам нужно увидеть, если это сканирование индексов и т. Д. – Andrew
вот изображение плана выполнения: http: //img31.imageshack .us/img31/899/readnewsplan.jpg на этом изображении, ItemNetwork - это то, что я назвал ItemCategory. они одинаковые. – Meysam
Если вам нужна текстовая версия, я также предоставил ее. – Meysam