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