MS SQL select top 1 тормозит
От: elmal  
Дата: 13.08.19 07:28
Оценка:
Не пойму что за хрень и как это лучше пофиксить.

Есть запрос:
select 
top 1
    asuUUID, skuUUID, timestamp, volume, recorddate
from
    stock
where
    tankUUID = ?
order by timestamp desc


Так вот, эта хрень тормозит более минуты, когда where фильтрует все записи. При этом если я поставлю top 14 и более, выполняется мгновенно. Индексы на tankUUID и timestamp есть.

Вопрос как эту хрень пофиксить наиболее универсально и просто, ну и понадежнее? Нагуглил через with index, да, работает, но это специфичная для ms sql инструкция, у меня тогда могут отвалиться другие базы. Я даже могу топ 14 (а то и 100) и брать программно первый элемент, это будет достаточно шустро работать, это не узкое место (когда не выполняется по 100 секунд естественно, даже секунда вполне приемлемо). Но где гарантии что на каких то данных там опять такая хрень не всплывет?
Re: MS SQL select top 1 тормозит
От: BlackEric http://black-eric.lj.ru
Дата: 13.08.19 07:37
Оценка: +2
Здравствуйте, elmal, Вы писали:

Сравните планы запрося для TOP 1 и TOP 14. Ну и здесь их покажите.
https://github.com/BlackEric001
Re: MS SQL select top 1 тормозит
От: night beast СССР  
Дата: 13.08.19 07:45
Оценка:
Здравствуйте, elmal, Вы писали:

E>Не пойму что за хрень и как это лучше пофиксить.


если явно индекс указать тормоза уходят?

E>Так вот, эта хрень тормозит более минуты, когда where фильтрует все записи. При этом если я поставлю top 14 и более, выполняется мгновенно. Индексы на tankUUID и timestamp есть.
Re[2]: MS SQL select top 1 тормозит
От: elmal  
Дата: 13.08.19 07:55
Оценка:
Здравствуйте, BlackEric, Вы писали:

BE>Здравствуйте, elmal, Вы писали:


BE>Сравните планы запрося для TOP 1 и TOP 14. Ну и здесь их покажите.

TOP 1:
SELECT    <-  Top       <= Nested Loops   <=  Index Scan (NonClustered)
Cost: 0%      Cost: 0%     (Inner Join)  <-|  (stock_timestamp_idx)
                           Cost: 0%        |  Cost: 0%
                                           |  
                                           |  Rid Lookup (Heap)
                                           |  (Stock)
                                           - Cost: 100%


TOP 14:
SELECT    <-  Top       Parallelism      <= Sort            <= Nested Loops   <= Compute Scalar <=  Index Scan (NonClustered)
Cost: 0%      Cost: 0%  (Gather Streams)    (Top N Sort)       (Inner Join)  <-| Cost: 0%           (stock_tankUUID_idx)
                        Cost: 0%            Cost: 0%           Cost: 0%        |                    Cost: 0%
                                                                               |  
                                                                               |  Rid Lookup (Heap)
                                                                               | (Stock)
                                                                               - Cost: 100%


При этом, что прикол:
DECLARE @topCount INT
SET @topCount = 1

SELECT TOP (@topCount)

Это работает быстро.

То есть понятно что берется другой индекс. Непонятно какого собственно черта.
Re[2]: MS SQL select top 1 тормозит
От: elmal  
Дата: 13.08.19 07:55
Оценка:
Здравствуйте, night beast, Вы писали:

NB>если явно индекс указать тормоза уходят?

Да
Re[3]: MS SQL select top 1 тормозит
От: _ABC_  
Дата: 13.08.19 08:10
Оценка:
Здравствуйте, elmal, Вы писали:

E>То есть понятно что берется другой индекс. Непонятно какого собственно черта.

Статистика обновлена?
Re[4]: MS SQL select top 1 тормозит
От: elmal  
Дата: 13.08.19 08:29
Оценка: :))) :))
Здравствуйте, _ABC_, Вы писали:

_AB>Статистика обновлена?

Угу. Теперь уже top 14 тоже тормозит, top 100 не тормозит .
Re[5]: MS SQL select top 1 тормозит
От: night beast СССР  
Дата: 13.08.19 08:35
Оценка:
Здравствуйте, elmal, Вы писали:

_AB>>Статистика обновлена?

E>Угу. Теперь уже top 14 тоже тормозит, top 100 не тормозит .

хз. иногда проще явно прописать индекс чем разбираться, что там мс намудрило.

индекс по обоим полям не решит проблему?
Re[6]: MS SQL select top 1 тормозит
От: elmal  
Дата: 13.08.19 08:44
Оценка:
Здравствуйте, night beast, Вы писали:

NB>индекс по обоим полям не решит проблему?

Не помогает. Ладно, поставил к чертям костыль с with index и проверкой что запущено с драйвером sqlServer, и если с этим, то хинты применять.
Re[5]: MS SQL select top 1 тормозит
От: _ABC_  
Дата: 13.08.19 08:45
Оценка:
Здравствуйте, elmal, Вы писали:

E>Угу. Теперь уже top 14 тоже тормозит, top 100 не тормозит .

Индексы на tankUUID и timestamp есть.

Какие именно индексы? create script можешь привести, пожалуйста?
Re[6]: MS SQL select top 1 тормозит
От: elmal  
Дата: 13.08.19 09:22
Оценка:
Здравствуйте, _ABC_, Вы писали:

_AB>Индексы на tankUUID и timestamp есть.

_AB>[/q]
_AB>Какие именно индексы? create script можешь привести, пожалуйста?
CREATE NONCLUSTERED INDEX [stock_tankUUID_idx] ON [dbo].[stock]
(
    [tankUUID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

CREATE NONCLUSTERED INDEX [stock_timestamp_idx] ON [dbo].[stock]
(
    [timestamp] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

Создавались автоматом от ORM в свое время.
Re[7]: MS SQL select top 1 тормозит
От: BlackEric http://black-eric.lj.ru
Дата: 13.08.19 09:43
Оценка:
Здравствуйте, elmal, Вы писали:

E>
E>CREATE NONCLUSTERED INDEX [stock_tankUUID_idx] ON [dbo].[stock]
E>(
E>    [tankUUID] ASC
E>)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

E>CREATE NONCLUSTERED INDEX [stock_timestamp_idx] ON [dbo].[stock]
E>(
E>    [timestamp] ASC
E>)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
E>

E>Создавались автоматом от ORM в свое время.

Странно. Вроде должно работать. А какая версия сервера? Все ли обновления стоят?
https://github.com/BlackEric001
Re[8]: MS SQL select top 1 тормозит
От: elmal  
Дата: 13.08.19 09:55
Оценка:
Здравствуйте, BlackEric, Вы писали:

BE>Странно. Вроде должно работать. А какая версия сервера? Все ли обновления стоят?

Вроде 13.0.5233.0. Хз что там админы ставили.
Re[8]: MS SQL select top 1 тормозит
От: _ABC_  
Дата: 13.08.19 10:08
Оценка: 5 (1) +1
Здравствуйте, BlackEric, Вы писали:

BE>Странно. Вроде должно работать.

От статистики зависит, какой из индексов брать. Или я уже туплю сильно.

Но, ИМХО, если будет индекс типа:
create index [stock_tankUUID_timestamp_idx] ON [dbo].[stock]([tankUUID] ASC, [timestamp] desc)

вот в этом случае должно для всех данных всегда использовать в таком запросе именно этот индекс и он должен быстро отрабатывать.
Отредактировано 13.08.2019 11:04 Does not matter . Предыдущая версия .
Re[7]: MS SQL select top 1 тормозит
От: Sinclair Россия https://github.com/evilguest/
Дата: 13.08.19 12:58
Оценка: 15 (3) +7
Здравствуйте, elmal, Вы писали:
E>Не помогает. Ладно, поставил к чертям костыль с with index и проверкой что запущено с драйвером sqlServer, и если с этим, то хинты применять.
Правильный ответ, тем временем — заменить индекс по tankUUID на индекс по (tankUUID, timestamp).
Порядок полей важен!
После этого все top x запросы будут быстрее, чем оригинальный top 14.

Причина вашей проблемы — простая: оба индекса — плохие. Какой бы из них ни был выбран, после его применения придётся выполнять потенциально дорогостоящую операцию. Сервер изо всех сил пытается предсказать, какая из них обойдётся дороже. И, естественно, не всегда угадывает — потому что ошибается в предсказании селективности предиката по tankUUID.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.