База данных существенно различается по запросу с индексами - PullRequest
6 голосов
/ 09 сентября 2010

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

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

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

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

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

alt text

Пожалуйста, игнорируйте текст «отсутствующий индекс». верно , что изменения в текущих индексах могут позволить более быстрый запрос с меньшим числом поисков, но здесь это не проблема (уже есть соответствующие индексы).Это Фактический План выполнения, где мы видим такие цифры, как Фактическое количество рядов.Например, в поиске по индексу фактическое количество строк равно 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());

Ответы [ 2 ]

1 голос
/ 10 сентября 2010

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

Также, пожалуйста, добавьте SQL-запрос, а также клиентский код.

Мысли:

  • Звучит как "5-20-дюймовые строки могут быть намного больше, чем
  • При неправильном прослушивании плана / параметров вы получите постоянно плохую производительность
  • Как может происходить запись в эту таблицу: достаточно для обновления статистики?
  • Есть ли проблема с типом данных?(например, объединение параметров и введение преобразования типов данных)
1 голос
/ 09 сентября 2010

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

Только одна идея, чтобы привести вещи в движение.

...