2016-01-21 3 views
3

У меня есть база данных размещается на Azure SQL Database и ниже схема для одной таблицы:Azure SQL Database - Индексация 10+ миллионы строк

CREATE TABLE [dbo].[Article](
    [ArticleHash] [bigint] NOT NULL, 
    [FeedHash] [bigint] NOT NULL, 
    [PublishedOn] [datetime] NOT NULL, 
    [ExpiresOn] [datetime] NOT NULL, 
    [DateCreated] [datetime] NOT NULL, 
    [Url] [nvarchar](max) NULL, 
    [Title] [nvarchar](max) NULL, 
    [Summary] [nvarchar](max) NULL 
CONSTRAINT [PK_dbo.Article] PRIMARY KEY CLUSTERED 
(
    [ArticleHash] ASC, 
    [FeedHash] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) 

У меня есть несколько запросов, которые я выполняющиеся, которые на самом деле замедлится, так как эта таблица содержит более 10 миллионов записей:

SELECT * 
FROM (SELECT ROW_NUMBER() OVER (ORDER BY PublishedOn DESC) page_rn, * 
     FROM Article 
     WHERE (FeedHash = -8498408432858355421 AND ExpiresOn > '2016-01-18 14:18:04.970') 
    ) paged 
WHERE page_rn>0 AND page_rn<=21 

И еще одно:

SELECT ArticleHash 
FROM Article 
WHERE (FeedHash = -8498408432858355421 
     AND ArticleHash IN (-1776401574438488264,996871668263687248,-5186412434178204433,6410875610077852481,-5428137965544411137,-5326808411357670185,2738089298373692963,9180394103094543689,8120572317154347382,-369910952783360989,1071631911959711259,1187953785740614613,6665010324256449533,3720795027036815325,-5458296665864077096,-5832860214011872788,-2941009192514997875,334202794706549486,-5579819992060984166,-696086851747657853,-7466754676679718482,-1461835507954240474,9021713212273098604,-6337379666850984216,5502287921912059432) 
     AND ExpiresOn >= '2016-01-18 14:28:25.883') 

Каков наилучший способ индексирования этой таблицы, чтобы запросы выполнялись ниже 300 мс? Возможно ли это на таком большом столе? Версия базы данных Azure SQL - S3.

Кроме того, много DELETE/INSERT действия выполняются на этой таблице, поэтому все индексы не должны влиять на производительность этих ...

+1

вам нужно индексировать столбец ExpiresOn и публиковатьOn – radar

+0

Я также добавлю 'FeedHash' в тот же индекс, что и' ExpiresOn'. – trailmax

+0

Также тщательная проверка плана выполнения скажет вам, где выполняется сканирование таблицы и какое значение. Поэтому попробуйте заменить эти таблицы на поиск индекса. – trailmax

ответ

0

Первый запрос будет извлечь выгоду из native pagination с OFFSET и FETCH:

SELECT * 
FROM Article 
WHERE FeedHash = -8498408432858355421 AND ExpiresOn > '2016-01-18 14:18:04.970' 
ORDER BY PublishedOn DESC 
OFFSET 0 FETCH NEXT 20 ROWS ONLY 

Второй запрос может извлечь выгоду из подстановки IN списка с INNER JOIN таблицы:

DECLARE @ArticleHashList AS TABLE (ArticleHashWanted bigint PRIMARY KEY); 
INSERT INTO @ArticleHashList (ArticleHashWanted) VALUES 
    (-1776401574438488264), 
    ( 996871668263687248), 
    (-5186412434178204433), 
    (6410875610077852481), 
    (-5428137965544411137), 
    (-5326808411357670185), 
    (2738089298373692963), 
    (9180394103094543689), 
    (8120572317154347382), 
    (-369910952783360989), 
    (1071631911959711259), 
    (1187953785740614613), 
    (6665010324256449533), 
    (3720795027036815325), 
    (-5458296665864077096), 
    (-5832860214011872788), 
    (-2941009192514997875), 
    ( 334202794706549486), 
    (-5579819992060984166), 
    (-696086851747657853), 
    (-7466754676679718482), 
    (-1461835507954240474), 
    (9021713212273098604), 
    (-6337379666850984216), 
    (5502287921912059432); 

SELECT ArticleHash 
FROM Article 
INNER JOIN @ArticleHashList On ArticleHash = ArticleHashWanted 
WHERE FeedHash = -8498408432858355421 AND ExpiresOn >= '2016-01-18 14:28:25.883'; 

Создание индексов в сроках должно помочь много:

CREATE INDEX idx_Article_PublishedOn ON Article (PublishedOn); 
CREATE INDEX idx_Article_ExpiresOn ON Article (ExpiresOn); 
0

для первого запроса я рекомендую этот индекс:

create index ix_Article_FeedHash_ExpiresOn_withInclude on Article(FeedHash,ExpiresOn) include (DateCreated, PublishedOn, Url, Title, Summary) 

и второй запрос Шоуда использовать кластерный индекс поиска, вы должны смотреть на план выполнения Actul, что будем бороться. Кроме того, я думаю, что у вас плохой кластерный индекс, так как valuse выглядит не растет, но должен быть случайным и, вероятно, индекс сильно фрагментирован, вы можете проверить его с запросом

select * from sys.dm_db_index_physical_stats(db_id(), object_id('Article'), null, null, 'DETAILED'); 

если avg_fragmentation_in_percent находится между 5 и 30, то вы можете исправить это по

alter index [clustered index name] on Article reorganize; 

если avg_fragmentation_in_percent выше, то 30, то вы можете исправить это

alter index [clustered index name] on Article rebuild; 

(если после реорганизации ничего не изменится т вы можете попробовать перестроить)

Смежные вопросы