Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Clustered Index Scan при Top(1)  [new]
IIIW
Member

Откуда:
Сообщений: 5
Доброго времени суток!
Столкнулся с интересной ситуацией.
Есть запрос, который упрощённо выглядит так:
SELECT TOP(1) *
FROM A
INNER JOIN B ON A.B_Id = B.Id
INNER JOIN C ON B.C_Id = C.Id
WHERE C.[some_column] = @value
ORDER BY A.Id

Запрос выполняется обычно очень долго (около 20 секунд) на "свежих" данных. Идёт Clustered Index Scan по индексу таблицы A (причём на свежих данных число прочитанных строк индекса составляет несколько миллионов (предполагаемое кол-во - 2000), т.е. в моём понимании пробегает индекс по порядку до первого совпадения).
При использовании хинтов запрос выполняется мгновенно, но не хочется зашивать в коде хинты.

Как можно улучшить скорость выполнения? (По всем FK есть индексы, статистика обновлена).
17 апр 17, 16:01    [20408087]     Ответить | Цитировать Сообщить модератору
 Re: Clustered Index Scan при Top(1)  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
Вы планы покажите, не надо их пересказывать.
17 апр 17, 16:09    [20408122]     Ответить | Цитировать Сообщить модератору
 Re: Clustered Index Scan при Top(1)  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
IIIW,

Нужно смотреть планы.

На вскидку, очень похоже на ситуацию:
http://www.queryprocessor.ru/rowgoal-on-non-uniform-distribution/

Если это она, то кроме как хинтами или флагами она не решается, т.к. ограничение модели.
Но хинты бывают разные, можно жестко прописывать названия индексов, что обычно не очень хорошо, а можно отключать row goal, вот так, например:
SQL Server 2016
'DISABLE_OPTIMIZER_ROWGOAL'
Causes SQL Server to generate a plan that does not use row goal adjustments with queries that contain TOP, OPTION (FAST N), IN, or EXISTS keywords. This is equivalent to trace flag 4138.
https://docs.microsoft.com/en-us/sql/t-sql/queries/hints-transact-sql-query

Вот статья про описание проблемы из MS:
https://support.microsoft.com/ru-ru/help/2667211/a-query-may-take-a-long-time-to-run-if-the-query-optimizer-uses-the-top-operator-in-sql-server-2008-r2-or-in-sql-server-2012

Вот еще из блогов MS:
https://blogs.msdn.microsoft.com/bartd/2012/03/14/row-goals-gone-rogue/

Если совсем без хинтов, можно попробовать заменить top 1 на declare @n =1; select top(@n) - по умолчанию, там оценка 100 строк, возможно, ее хватит, чтобы вразумить сервер, можно увеличить оценку дописав optimze for (@n = ...) - но это уже опять же хинт.
Короче, почитайте, разберитесь, попробуйте предложенные варианты.

Если это не ваш случай, тогда выкладывайте планы.
17 апр 17, 16:22    [20408172]     Ответить | Цитировать Сообщить модератору
 Re: Clustered Index Scan при Top(1)  [new]
IIIW
Member

Откуда:
Сообщений: 5
Прикладывают скан.

К сообщению приложен файл. Размер - 30Kb
17 апр 17, 16:36    [20408252]     Ответить | Цитировать Сообщить модератору
 Re: Clustered Index Scan при Top(1)  [new]
IIIW
Member

Откуда:
Сообщений: 5


К сообщению приложен файл. Размер - 29Kb
17 апр 17, 16:37    [20408256]     Ответить | Цитировать Сообщить модератору
 Re: Clustered Index Scan при Top(1)  [new]
IIIW
Member

Откуда:
Сообщений: 5
Запрос такой (генерируется через ORM):

	DECLARE @p__linq__0 INT=202050

	SELECT top(1) *
        FROM     [dbo].[Cases] AS [Extent1] --with (FORCESEEK)
        INNER JOIN [dbo].[Relations] AS [Extent2] ON [Extent1].[RelationId] = [Extent2].[Id]
        INNER JOIN [dbo].[ImportDocuments] AS [Extent3] ON [Extent2].[ImportDocumentId] = [Extent3].[Id]
        WHERE ([Extent3].[InnerId] IN (@p__linq__0)) AND (([Extent3].[ClientId] = @p__linq__0) OR (([Extent3].[ClientId] IS NULL) AND (@p__linq__0 IS NULL)))
		ORDER BY [Extent1].[Id] ASC
17 апр 17, 16:44    [20408282]     Ответить | Цитировать Сообщить модератору
 Re: Clustered Index Scan при Top(1)  [new]
IIIW
Member

Откуда:
Сообщений: 5
SomewhereSomehow, спасибо - у меня похожая ситуация. Буду разбираться.
17 апр 17, 17:14    [20408392]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить