Чтение базы данных резко различается по запросу с индексами

У меня есть запрос, который имеет соответствующие индексы и показан в плане запроса с оценочной стоимостью поддерева около 1,5. План показывает поиск по индексу, за которым следует поиск по ключу, что нормально для запроса, который, как ожидается, вернет 1 строку из набора от 5 до 20 строк (т. е. поиск по индексу должен найти от 5 до 20 строк, а после 5–20 строк). Key Lookups, мы должны вернуть 1 строку).

При интерактивном выполнении запрос возвращается почти сразу. Тем не менее, утренние трассировки БД показывают, что время выполнения в реальном времени (веб-приложение) сильно различается; обычно запрос занимает ‹ 100 чтений БД и фактически 0 времени выполнения... но мы получаем несколько запусков, которые потребляют> 170 000 чтений БД и время выполнения до 60 с (больше, чем наше значение тайм-аута).

Чем можно объяснить такую ​​изменчивость в чтении с диска? Я пробовал сравнивать запросы в интерактивном режиме и использовать планы фактического выполнения из двух параллельных прогонов со значениями фильтра, взятыми из быстрых и медленных прогонов, но в интерактивном режиме они практически не показывают разницы в используемом плане.

Я также попытался определить другие запросы, которые могли блокировать этот, но я не уверен, что это так сильно повлияет на чтение БД... и в любом случае этот запрос, как правило, был худшим для времени выполнения в моих журналах трассировки.

Обновление. Вот пример плана, созданного при интерактивном выполнении запроса:

альтернативный текст

Пожалуйста игнорируйте текст "отсутствует индекс". Верно, что изменения в текущих индексах могут обеспечить более быстрый запрос с меньшим количеством операций поиска, но здесь проблема не в этом (уже есть соответствующие индексы). Это фактический план выполнения, в котором мы видим такие цифры, как фактическое количество строк. Например, при поиске по индексу фактическое количество строк равно 16, а стоимость ввода-вывода равна 0,003. Стоимость ввода-вывода такая же, как и при поиске ключа.

Обновление 2. Результаты трассировки этого запроса:

exec sp_executesql N'select [...column list removed...] from ApplicationStatus where ApplicationGUID = @ApplicationGUID and ApplicationStatusCode = @ApplicationStatusCode;',N'@ApplicationGUID uniqueidentifier,@ApplicationStatusCode bigint',@ApplicationGUID='ECEC33BC-3984-4DA4-A445-C43639BF7853',@ApplicationStatusCode=10

Запрос создается с использованием класса Gentle.Framework SqlBuilder, который строит параметризованные запросы следующим образом:

SqlBuilder sb = new SqlBuilder(StatementType.Select, typeof(ApplicationStatus));
sb.AddConstraint(Operator.Equals, "ApplicationGUID", guid);
sb.AddConstraint(Operator.Equals, "ApplicationStatusCode", 10);
SqlStatement stmt = sb.GetStatement(true);
IList apps = ObjectFactory.GetCollection(typeof(ApplicationStatus), stmt.Execute());

person Nij    schedule 09.09.2010    source источник


Ответы (2)


Могут ли данные быть удалены из кеша? Это может быть объяснением того, почему при горячем кеше (данные уже находятся в памяти) количество записанных операций чтения очень низкое... а затем, когда данных больше нет в ОЗУ, количество операций чтения будет увеличиваться, поскольку он должен считывать их с диска. снова.

Всего одна идея, чтобы сдвинуть дело с мертвой точки.

person AdaTheDev    schedule 09.09.2010
comment
я так не думаю; Насколько я понимаю, профилирование покажет чтение логического диска, даже если оно было извлечено из кеша. Однако не то, в чем я уверен. - person Nij; 09.09.2010

Запустите профилировщик, чтобы увидеть, обновляется ли статистика примерно в то же время. Или просто посмотреть, что еще происходит.

Кроме того, добавьте SQL-запрос и клиентский код.

Мысли:

  • Похоже, ваши «5-20» строк могут быть намного больше, чем это
  • С плохим обнюхиванием плана/параметра вы получите постоянно плохую производительность.
  • Как могут происходить записи в эту таблицу: достаточно для обновления статистики?
  • Есть ли проблема с типом данных? (например, объединение параметров и введение преобразования типа данных)
person gbn    schedule 10.09.2010
comment
@gbn: Насколько я вижу, статистика по задействованным индексам была обновлена ​​около 3 дней назад (у нас есть работа, которая заставляет это делать). Я добавил скриншот плана запроса (при интерактивном запуске). Я не верю, что есть проблема с типом данных. Это таблица, в которую часто добавляются записи (в идентификационном ПК)... Мне нужно будет провести некоторое исследование, при каких обстоятельствах это может привести к обновлению статистики и будет ли это отображаться при чтении запроса. - person Nij; 10.09.2010
comment
@Nij: План, очевидно, в порядке (ну, его можно было бы охватить) и здесь не помогает ... код SQL и клиентский код были бы полезны. - person gbn; 10.09.2010
comment
@gbn: запрос показан на снимке экрана вверху вверху. Я не на 100% понимаю, что вы имеете в виду, когда говорите о клиентском коде, но если вы имеете в виду что-то вроде исходного кода C #, я не уверен, как это повлияет на чтение БД? - person Nij; 10.09.2010
comment
@Nij: из того, как вы параметризуете SQL-запрос, который меня интересует - person gbn; 10.09.2010
comment
@gbn: Еще одно обновление для вас выше. Я не думаю, что мы делаем что-то особенно необычное с кодовой частью; однако из-за (очень старого) ORM, который мы используем; Gentle.Framework, у нас нет реального выбора, как отправить этот запрос. - person Nij; 11.09.2010
comment
@Nij: Какой тип данных @ApplicationStatusCode в таблице, пожалуйста? - person gbn; 11.09.2010