Добро пожаловать в форум, Guest >> Войти | Регистрация | Поиск | Правила | | В избранное | Подписаться | ||
Все форумы / Microsoft SQL Server |
![]() ![]() |
Yuri Abele Member Откуда: Латвия> Литва > Тольятти > Wiesbaden > Karlsruhe Сообщений: 1661 |
Всем привет! Вот такой запрос (вместо многоточий между фигурными скобками где-то килобайт в синтаксисе JSON): MERGE FileMetaData.[File] AS TARGET USING (VALUES ( 111, '2019-03-07 08:21:50', N'{ ... }' ), ( 222, '2019-03-07 08:21:50', N'{ ... }' ), ...... ( 999, '2019-03-07 08:21:50', N'{ ... }' ) ) AS SOURCE( Id, LastScanTime, MetaInfo ) ON 1=1 AND TARGET.Id = SOURCE.Id WHEN MATCHED THEN UPDATE SET MetaInfo = SOURCE.MetaInfo, LastScanTime = SOURCE.LastScanTime; Пораждает какой-то дикий execution plan (на картинке). Почему так? К сообщению приложен файл. Размер - 48Kb |
7 мар 19, 10:59 [21827053] Ответить | Цитировать Сообщить модератору |
Ivan Durak Member Откуда: Minsk!!! Сообщений: 3646 |
нормальный план. засканить кусок кластерного индекса один раз. Это куда лучше чем сотню раз в нем по одной записи искать. даже с учетом сортировки скаляров. Хотя может сортировка скаляров и тянет.... из-за килобайтов джейсона. |
7 мар 19, 11:08 [21827059] Ответить | Цитировать Сообщить модератору |
felix_ff Member Откуда: Moscow Сообщений: 1698 |
Yuri Abele, Вас смущает диапазон поиска Id? что в гистограмме FileMetaData.[File].PK? |
7 мар 19, 11:11 [21827062] Ответить | Цитировать Сообщить модератору |
Yuri Abele Member Откуда: Латвия> Литва > Тольятти > Wiesbaden > Karlsruhe Сообщений: 1661 |
В т.ч.. Зачем он так ищет?: ID >= ... AND ID <= ... |
||
7 мар 19, 11:28 [21827091] Ответить | Цитировать Сообщить модератору |
Yuri Abele Member Откуда: Латвия> Литва > Тольятти > Wiesbaden > Karlsruhe Сообщений: 1661 |
И зачем ему при поиске по кластерному индексу, вытаскивать имеющиеся значаение поля MetaInfo? Я же не сравниваю его ни с чем, просто перезаписываю |
7 мар 19, 11:32 [21827099] Ответить | Цитировать Сообщить модератору |
invm Member Откуда: Москва Сообщений: 9636 |
План покажите в формате sqlplan. |
7 мар 19, 11:37 [21827110] Ответить | Цитировать Сообщить модератору |
felix_ff Member Откуда: Moscow Сообщений: 1698 |
Yuri Abele,WHEN MATCHED THEN UPDATE SET MetaInfo = SOURCE.MetaInfo, вы его переиспользуете в своей update, поэтому и тянет. а по диапазону, необходимо посмотреть гистограмму. да и вообще бы желательно весь план в формате .sqlplan а не скриншот. |
7 мар 19, 11:38 [21827116] Ответить | Цитировать Сообщить модератору |
Yuri Abele Member Откуда: Латвия> Литва > Тольятти > Wiesbaden > Karlsruhe Сообщений: 1661 |
Подсократил в плане количество строк из VALUES TABLE. В оригинале их 100. К сообщению приложен файл (Execution_Plan.sqlplan - 67Kb) cкачать ![]() |
7 мар 19, 11:58 [21827150] Ответить | Цитировать Сообщить модератору |
Yuri Abele Member Откуда: Латвия> Литва > Тольятти > Wiesbaden > Karlsruhe Сообщений: 1661 |
Пораллельно с обновлением [MetaInfo] бежит еще процесс, который обновляет поле [HashSum] (см. ниже) - план выполнения идентичный предыдущему. Оба эти запроса еще недавно выполнялись, приактически, мгновенно. Теперь же, минимум минуту! MERGE FileMetaData.[File] WITH (ROWLOCK) AS TARGET USING (VALUES ( 8098920, '2019-03-07 09:42:03', 0xDB5873057F26404AE9DF216EF7242D36F4916245C0EE888B181A207F0D911327 ), ( 8098921, '2019-03-07 09:42:03', 0xBA90CEB46D7222EC7A091055827233F616B110466FEA86D9DAA1B0973F520F98 ), ( 8098923, '2019-03-07 09:42:03', 0xFBBEAD9D492D31C4D13B4683E0B9FFF6A2EF843CD61CE3EB865B35FF54DEEEA9 ), ..... ) AS SOURCE( Id, LastScanTime, HashSum ) ON 1=1 AND TARGET.Id = SOURCE.Id WHEN MATCHED THEN UPDATE SET HashSum = SOURCE.HashSum, LastScanTime = SOURCE.LastScanTime; |
7 мар 19, 12:04 [21827160] Ответить | Цитировать Сообщить модератору |
Yuri Abele Member Откуда: Латвия> Литва > Тольятти > Wiesbaden > Karlsruhe Сообщений: 1661 |
Ой, вот этого в запросе нет. Скопировал нечайно текст из экспериментов:... WITH (ROWLOCK) ... |
7 мар 19, 12:05 [21827164] Ответить | Цитировать Сообщить модератору |
Ivan Durak Member Откуда: Minsk!!! Сообщений: 3646 |
реальный план покеж |
7 мар 19, 12:26 [21827181] Ответить | Цитировать Сообщить модератору |
felix_ff Member Откуда: Moscow Сообщений: 1698 |
Yuri Abele, Так а в чем собственно проблема? Вы приложили предполагаемый план, а не фактический. При этом он походу он закэширован, поскольку у вас инструкция для 3 граничных значений, а по оценкам он считает что будет обрабатывать 100 строк. (правда это мое предположение возможно действительно по данному распределению будет 100 строк) сделайте dbcc show_statistics ([VEA].[FileMetaData].[File], [FileMetaData.File.PK.Id]) with histogram при этом могу предположить: если у вас два параллельных merge, один временно блокирует другого |
7 мар 19, 12:29 [21827186] Ответить | Цитировать Сообщить модератору |
invm Member Откуда: Москва Сообщений: 9636 |
При компиляции запроса из ваших values определяются минимальное и максимальное значения id и далее используются для сканирования диапазона кластерного индекса вместо его полного сканирования. |
||
7 мар 19, 12:37 [21827204] Ответить | Цитировать Сообщить модератору |
Yuri Abele Member Откуда: Латвия> Литва > Тольятти > Wiesbaden > Karlsruhe Сообщений: 1661 |
Выдает таблицу в 195 строк. Как ее показать? Скриншотом? P.S. А смысл? Это же поле CLUSTERED PRIMARY KEY - там по определению каждое значение только один раз. |
||
7 мар 19, 12:50 [21827220] Ответить | Цитировать Сообщить модератору |
Yuri Abele Member Откуда: Латвия> Литва > Тольятти > Wiesbaden > Karlsruhe Сообщений: 1661 |
В приложении "живой" план выполнения. Я взял только для HashSum, он (в байтах) покомпактнее. И я для строк VALUES TABLE уже из плана вырезал большую часть, оставил только 5 Rows. Иначе файл слишком здоровый К сообщению приложен файл (Execution_Plan.sqlplan - 90Kb) cкачать ![]() |
7 мар 19, 12:55 [21827228] Ответить | Цитировать Сообщить модератору |
felix_ff Member Откуда: Moscow Сообщений: 1698 |
Yuri Abele, ну пусть Вас не смущает интервал, он берет для операции поиска по кластерному индексу интервал границ заведомо меньший или равный чем минимальное значение и заведомо больший или равный максимального значения из вашего набора значений. в этом случае это границы [8098917; 8099044] в таком диапазоне поиск по индексу выдаст вам 128 строк, но поскольку значений в (using values ) у вас 100 ему надо убрать лишние 28 строк, на что и делается constant scan + sort для возможности применения merge join двух наборов. 8098917 - значение у вас присутствует в списке значений, 8099044 - я не увидел или вы его вырезали или оно подогнано оптимизатором из гистограммы статистики. |
7 мар 19, 14:08 [21827319] Ответить | Цитировать Сообщить модератору |
Yuri Abele Member Откуда: Латвия> Литва > Тольятти > Wiesbaden > Karlsruhe Сообщений: 1661 |
Да, я вырезал. Там пакетами по 100 строк бомбит. |
||
7 мар 19, 14:34 [21827357] Ответить | Цитировать Сообщить модератору |
Yuri Abele Member Откуда: Латвия> Литва > Тольятти > Wiesbaden > Karlsruhe Сообщений: 1661 |
Большущее спасибо за помощь по анализу! |
7 мар 19, 15:26 [21827442] Ответить | Цитировать Сообщить модератору |
Yuri Abele Member Откуда: Латвия> Литва > Тольятти > Wiesbaden > Karlsruhe Сообщений: 1661 |
Почистил через JSON_MODIFY ненужные элементы в нагенеренных MetaInfo, Потом прогнал INDEX REORGONIZE ALL по этой таблице. Итог - размер таблицы в байтах уменьшился порядка в 50 раз. Тут уже можно дышать :-) |
8 мар 19, 09:59 [21827843] Ответить | Цитировать Сообщить модератору |
Все форумы / Microsoft SQL Server | ![]() |