|
Не используется индекс.
|
|||
---|---|---|---|
#18+
Добрый день! Имеем сервер Microsoft SQL Server 2019 (RTM-CU14) (KB5007182) - 15.0.4188.2 (X64) Есть таблица 25 млн записей. Для таблицы есть 2 индекса: CREATE UNIQUE CLUSTERED INDEX [_AccumRg35623_1] ON [dbo].[_AccumRg35623] ( [_Period] ASC, [_RecorderTRef] ASC, [_RecorderRRef] ASC, [_LineNo] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY] CREATE UNIQUE NONCLUSTERED INDEX [_AccumRg35623_2] ON [dbo].[_AccumRg35623] ( [_RecorderTRef] ASC, [_RecorderRRef] ASC, [_LineNo] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY] Есть запрос SELECT 0x00000000000000000000000000000000, MIN(T1._Period) FROM dbo._AccumRg35623 T1 WHERE (T1._RecorderTRef = 0x000001EB AND T1._RecorderRRef = 0x9C575CB90199817511EC632194753AD9) В какой то момент времени запрос перестал использовать индекс _AccumRg35623_2 и делает сканирование по индексу _AccumRg35623_1. Сканирование занимает около 3,5 сек. Процедурные кэши сбрасывались, статистики обновлялись, индексы перестраивались. Результат тот же. если добавить 3й индекс только по полям _RecorderTRef и _RecorderRRef то запрос начинает работать по нему. Выборка мгновенная(меньше 1 мс), т.к. обычно в таблице существует 1 запись удовлетворяющая условиям поиска. Индексы _AccumRg35623_1 и _AccumRg35623_2 поменять нельзя. Запрос тоже. Создавать дублирующий индекс не хочется, выглядит избыточным. Да и подобных ситуаций может быть много. Аналогичные по структуре таблицы исчисляются сотнями. На текущий момент есть проблема только с двумя. План запроса со сканированием прикладываю. Прошу помочь разобраться почему сервер не использует индекс _AccumRg35623_2. ... |
|||
:
Нравится:
Не нравится:
|
|||
23.12.2021, 15:03 |
|
Не используется индекс.
|
|||
---|---|---|---|
#18+
Аднаэснек Код: sql 1. 2. 3. 4.
Есть запрос Код: sql 1. 2. 3. 4. 5. 6. 7.
T1._Period, Карл!!! Это означает lookup. Если сервер считает, что lookup-ов будет многовато - он включает сканирование. Для начала, статистику обнови with FULLSCAN. ... |
|||
:
Нравится:
Не нравится:
|
|||
23.12.2021, 15:08 |
|
Не используется индекс.
|
|||
---|---|---|---|
#18+
Код: sql 1. 2. 3. 4. 5. 6. 7. 8.
... |
|||
:
Нравится:
Не нравится:
|
|||
23.12.2021, 15:12 |
|
Не используется индекс.
|
|||
---|---|---|---|
#18+
aleks222, Делали, не помогало. На всякий случай сделал еще раз UPDATE STATISTICS _AccumRg35623 WITH FULLSCAN, MAXDOP = 0, PERSIST_SAMPLE_PERCENT = ON; результат не изменился. ... |
|||
:
Нравится:
Не нравится:
|
|||
23.12.2021, 15:18 |
|
Не используется индекс.
|
|||
---|---|---|---|
#18+
Konst_One, Не работает, это пробовали. ... |
|||
:
Нравится:
Не нравится:
|
|||
23.12.2021, 15:23 |
|
Не используется индекс.
|
|||
---|---|---|---|
#18+
Аднаэснек Konst_One, Не работает, это пробовали. Не верю! (с) Станиславский. ЗЫ. Хотя... размеры то данных те же получаются. Может и наплевать. ... |
|||
:
Нравится:
Не нравится:
|
|||
23.12.2021, 15:26 |
|
Не используется индекс.
|
|||
---|---|---|---|
#18+
aleks222 Это означает lookup. Это означает Lookup только если во втором индексе поля _Period нет. А оно там есть, т.к. оно используется в ключе кластерного индекса и, соответственно, будет дублироваться во все записи индексов некластерных. (поэтому же и include не помогает) Кто сомневается - может посмотреть с помощью DBCC PAGE Аднаэснек, можете получить план с использованием _AccumRg35623_2? Например, прям явно указать через хинт index: Код: sql 1. 2. 3. 4. 5. 6. 7.
А то пока только половина картины есть, непонятно, чем серверу такой план не нравится ... |
|||
:
Нравится:
Не нравится:
|
|||
23.12.2021, 15:33 |
|
Не используется индекс.
|
|||
---|---|---|---|
#18+
0wl, Во вложении ... |
|||
:
Нравится:
Не нравится:
|
|||
23.12.2021, 15:37 |
|
Не используется индекс.
|
|||
---|---|---|---|
#18+
Аднаэснек, План без хинта приведите. Да странно. Код: sql 1.
при Код: sql 1.
должен без хинта использовать индекс. ... |
|||
:
Нравится:
Не нравится:
|
|||
23.12.2021, 16:00 |
|
Не используется индекс.
|
|||
---|---|---|---|
#18+
PaulWist Аднаэснек, План без хинта приведите. план прикреплен к первому сообщению ... |
|||
:
Нравится:
Не нравится:
|
|||
23.12.2021, 17:05 |
|
Не используется индекс.
|
|||
---|---|---|---|
#18+
Аднаэснек Konst_One, Не работает, это пробовали. попробуйте создать сжатый индекс это поможет сиквелу принять решение в пользу этого индекса - размер меньше, читать меньше ... |
|||
:
Нравится:
Не нравится:
|
|||
23.12.2021, 17:28 |
|
Не используется индекс.
|
|||
---|---|---|---|
#18+
Аднаэснек ... CREATE UNIQUE NONCLUSTERED INDEX [_AccumRg35623_2] ON [dbo].[_AccumRg35623] ( [_RecorderTRef] ASC, [_RecorderRRef] ASC, [_LineNo] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY] Немного странные индексы, я правильно понимаю, что они были созданы платформой 1С? и именно поэтому их изменять нельзя ? Странно: 1. Наименование (у платформенных индексов названия обычно не "_AccumRg35623_2", а "_AccumRg35623_ByRecorder") 2. Состав (начиная с платформы 8.3.8 первым в составе, обычно идёт "_Fld1389", - разделитель данных) Если состав действительное не "[_RecorderTRef] ,[_RecorderRRef] ,[_LineNo] " , а "[_Fld1389], [_RecorderTRef] ,[_RecorderRRef] ,[_LineNo]" Тогда индекс в вашем запросе может игнорироваться из-за того, что не указано первое значение в составе кластерного индекса. На прошлой неделе были аналогичные проблемы с таблицей в 450 млн записей. Решалось через "UPDATE STATISTICS _AccumRg35623 WITH FULLSCAN" ... про "PERSIST_SAMPLE_PERCENT = ON" - прочитал, вроде как должно быть лучше, но на всякий случай попробуйте без него ... ... |
|||
:
Нравится:
Не нравится:
|
|||
23.12.2021, 18:01 |
|
Не используется индекс.
|
|||
---|---|---|---|
#18+
komrad попробуйте создать сжатый индекс это поможет сиквелу принять решение в пользу этого индекса - размер меньше, читать меньше Сделал для индекса _AccumRg35623_2 DATA_COMPRESSION = PAGE После выполнения сбросил процедурный кэш. Поведение не поменялось. ... |
|||
:
Нравится:
Не нравится:
|
|||
23.12.2021, 18:22 |
|
Не используется индекс.
|
|||
---|---|---|---|
#18+
Аднаэснек, попробуйте хинт FORCE_LEGACY_CARDINALITY_ESTIMATION. ... |
|||
:
Нравится:
Не нравится:
|
|||
23.12.2021, 18:42 |
|
Не используется индекс.
|
|||
---|---|---|---|
#18+
0wl aleks222 Это означает lookup. Это означает Lookup только если во втором индексе поля _Period нет. А оно там есть, т.к. оно используется в ключе кластерного индекса и, соответственно, будет дублироваться во все записи индексов некластерных. (поэтому же и include не помогает) Кто сомневается - может посмотреть с помощью DBCC PAGE Аднаэснек, можете получить план с использованием _AccumRg35623_2? Например, прям явно указать через хинт index: Код: sql 1. 2. 3. 4. 5. 6. 7.
А то пока только половина картины есть, непонятно, чем серверу такой план не нравится Да, я тоже считаю, что это всемирный заговор жидомасонов. ... |
|||
:
Нравится:
Не нравится:
|
|||
23.12.2021, 19:59 |
|
Не используется индекс.
|
|||
---|---|---|---|
#18+
Аднаэснек PaulWist Аднаэснек, План без хинта приведите. план прикреплен к первому сообщению Пардон, не увидел. Похоже на parameter sniffing Код: sql 1.
... |
|||
:
Нравится:
Не нравится:
|
|||
23.12.2021, 20:04 |
|
Не используется индекс.
|
|||
---|---|---|---|
#18+
Аднаэснек, Кстати, для общности эксперимента выполните скрипт без параметров и без хинта (в первом посте план запроса с параметрами). Код: sql 1. 2. 3. 4. 5. 6. 7.
... |
|||
:
Нравится:
Не нравится:
|
|||
24.12.2021, 09:42 |
|
Не используется индекс.
|
|||
---|---|---|---|
#18+
ErMiValRU Аднаэснек ... CREATE UNIQUE NONCLUSTERED INDEX [_AccumRg35623_2] ON [dbo].[_AccumRg35623] ( [_RecorderTRef] ASC, [_RecorderRRef] ASC, [_LineNo] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY] Немного странные индексы, я правильно понимаю, что они были созданы платформой 1С? и именно поэтому их изменять нельзя ? Странно: 1. Наименование (у платформенных индексов названия обычно не "_AccumRg35623_2", а "_AccumRg35623_ByRecorder") 2. Состав (начиная с платформы 8.3.8 первым в составе, обычно идёт "_Fld1389", - разделитель данных) Если состав действительное не "[_RecorderTRef] ,[_RecorderRRef] ,[_LineNo] " , а "[_Fld1389], [_RecorderTRef] ,[_RecorderRRef] ,[_LineNo]" Тогда индекс в вашем запросе может игнорироваться из-за того, что не указано первое значение в составе кластерного индекса. На прошлой неделе были аналогичные проблемы с таблицей в 450 млн записей. Решалось через "UPDATE STATISTICS _AccumRg35623 WITH FULLSCAN" ... про "PERSIST_SAMPLE_PERCENT = ON" - прочитал, вроде как должно быть лучше, но на всякий случай попробуйте без него ... Да, это 1С. Индексы созданы платформой, менять их крайне не желательно(нельзя) 1.Наименование индекса зависит от версии платформы в которой создавался индекс. Наименование вида _AccumRg35623_ByRecorder было характерно для 8.2. Если сделать реструктуризацию на последней версии платформы то индекс будет иметь имя вида _AccumRg35623_2 ,по крайней мере у меня так. Возможно причина в методе реструктуризации. Не исследовал данный вопрос. 2. Разделители данных можно использовать, а можно не использовать. Зависит от логики конфигурации. В моем случае его нет. Привожу структуру таблицы: CREATE TABLE [dbo].[_AccumRg35623]( [_Period] [datetime2](0) NOT NULL, [_RecorderTRef] [binary](4) NOT NULL, [_RecorderRRef] [binary](16) NOT NULL, [_LineNo] [numeric](9, 0) NOT NULL, [_Active] [binary](1) NOT NULL, [_RecordKind] [numeric](1, 0) NOT NULL, [_Fld35624RRef] [binary](16) NOT NULL, [_Fld35625RRef] [binary](16) NOT NULL, [_Fld35626] [datetime2](0) NOT NULL, [_Fld35627] [numeric](15, 3) NOT NULL ) ON [PRIMARY] Насчет "UPDATE STATISTICS _AccumRg35623 WITH FULLSCAN" Только решил проверить, запустил запрос чтобы опять увидеть скан, и о чудо - запрос выполнился по индексу _AccumRg35623_2. Не люблю совпадений. Все что менялось это ночью был перезагружен сервер. Но на счастье(или наоборот) у меня есть еще 1 таблица с таким же точно поведеним - _AccumRg25415. Так вот на ней скан продолжается. Отказ от PERSIST_SAMPLE_PERCENT в UPDATE STATISTICS не влияет. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.12.2021, 11:33 |
|
Не используется индекс.
|
|||
---|---|---|---|
#18+
Владислав Колосов Аднаэснек, попробуйте хинт FORCE_LEGACY_CARDINALITY_ESTIMATION. Помогло. План прикладываю. Имя таблицы поменялось по причине того что _AccumRg35623 чудесным образом вылечилась, но проблема продолжает воспроизводится на другой таблице _AccumRg25415. Структура таблиц и индексов идентичны. Размер тоже. Сейчас буду детальнее читать что дает использование FORCE_LEGACY_CARDINALITY_ESTIMATION, если поясните "на пальцах" сильно поможет в понимании проблемы. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.12.2021, 11:38 |
|
Не используется индекс.
|
|||
---|---|---|---|
#18+
PaulWist Аднаэснек пропущено... план прикреплен к первому сообщению Пардон, не увидел. Похоже на parameter sniffing Код: sql 1.
Почитал про parameter sniffing. Везде упоминаются хранимые процедуры. В моем случае их нет. Не подскажите, распространяется ли это на параметризированные запросы? ... |
|||
:
Нравится:
Не нравится:
|
|||
24.12.2021, 11:54 |
|
Не используется индекс.
|
|||
---|---|---|---|
#18+
если вы долбите sql своими всегда разными adhoc-запросами, то что вы ожидаете от бедного сервера, если он не знает какой план вам подобрать из кэша? ... |
|||
:
Нравится:
Не нравится:
|
|||
24.12.2021, 12:21 |
|
Не используется индекс.
|
|||
---|---|---|---|
#18+
Аднаэснек Почитал про parameter sniffing. Везде упоминаются хранимые процедуры. В моем случае их нет. Не подскажите, распространяется ли это на параметризированные запросы? 1. Запрос параметризирован Код: sql 1. 2. 3. 4.
2. Почитать на предмет "распространяется ли это на параметризированные запросы?", ответ ДА. https://sqlperformance.com/2013/08/t-sql-queries/parameter-sniffing-embedding-and-the-recompile-options ... |
|||
:
Нравится:
Не нравится:
|
|||
24.12.2021, 12:33 |
|
Не используется индекс.
|
|||
---|---|---|---|
#18+
PaulWist Аднаэснек, Кстати, для общности эксперимента выполните скрипт без параметров и без хинта (в первом посте план запроса с параметрами). Код: sql 1. 2. 3. 4. 5. 6. 7.
К сожалению не осилил сделать это в SSMS. Не подскажите как это реализовать? ... |
|||
:
Нравится:
Не нравится:
|
|||
24.12.2021, 12:36 |
|
Не используется индекс.
|
|||
---|---|---|---|
#18+
Konst_One если вы долбите sql своими всегда разными adhoc-запросами, то что вы ожидаете от бедного сервера, если он не знает какой план вам подобрать из кэша? Я догадываюсь что он не знает. Чем ему помочь в сложившейся ситуации я пока не знаю. Повлиять на сам запрос явным образом(переписать его) не представляется возможным потому что запрос генерирует платформа 1С и разработчик на языке 1С не имеет возможности влиять на эти запросы. В большинстве случаев проблем нет, но бывают исключения. По-этому и ветка появилась. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.12.2021, 12:42 |
|
|
start [/forum/topic.php?fid=46&msg=40122678&tid=1683962]: |
0ms |
get settings: |
11ms |
get forum list: |
15ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
48ms |
get topic data: |
8ms |
get forum data: |
2ms |
get page messages: |
59ms |
get tp. blocked users: |
1ms |
others: | 242ms |
total: | 394ms |
0 / 0 |