Плохая производительность, когда SQL Server повторно использует кэшированный план запросов в более крупной компании

#sql-server

Вопрос:

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

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

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

Проблема возникает, когда один и тот же запрос выполняется в более крупной компании, SQL повторно использует сгенерированный план запроса от более мелкой компании, что приводит к замедлению работы в более крупной компании.

Есть ли лучший вариант вместо использования индекса подсказки/ индекса покрытия?

Некоторые подробности:

Таблица продаж:

 | Company | RunningNumber | Account | SalesAmount | Status|
 
  • Кластеризованный индекс включен Company, RunningNumber
  • У меня также есть некластеризованный индекс на Account, Company

Запрос

 SELECT SUM(SalesAmount) 
FROM SalesTable 
WHERE Company = @P1 AND Account = @P2
 

Комментарии:

1. Включить учетную запись в кластеризованный индекс после компании?

2. Посмотрите на опцию (перекомпиляция)

3. Некластеризованный индекс on (Account, Division) не является охватывающим индексом для вашего запроса, поскольку он не включает все необходимые столбцы. В лучшем случае он может использоваться Account для фильтрации, но все равно потребуется доступ к строкам таблицы для поиска Company и SalesAmount .

4. Пожалуйста, поделитесь обоими планами запросов через brentozar.com/pastetheplan . Пожалуйста, также добавьте полную таблицу и определения индексов к вашему вопросу. Лучшим показателем здесь, скорее всего, будет (Company, Account) INCLUDE (SalesAmount)

5. Кроме того, хотя option (recompile) это может быть хорошей идеей, это происходит за счет постоянной перекомпиляции. Альтернативой является безопасное внедрение @P1 непосредственно в запрос, это означает, что вы получаете один план, скомпилированный один раз в Company