ВЫБЕРИТЕ с проблемой производительности «datetime> string» в EF4 / SQL Server 2008 - PullRequest
1 голос
/ 05 сентября 2011

Я использую EntityFramework 4 для доступа к базе данных SQL Server 2008.

Один из SQL-запросов, генерируемых EF, имеет поведение, которое я не могу объяснить. Запрос выглядит так:

SELECT tableA.field1, tableA.field2, ...
FROM tableA join tableB on tableA.field1 = tableB.field1
WHERE
    tableA.field2 > '20110825'
    and tableA.field3 in ('a', 'b', 'c,')
    and tableB.field4 = 'xxx'

Где tableA.field2 - datetime not null, а остальные поля - varchars. Таблица A содержит около 1,5 миллионов записей, таблица B содержит около 2 миллионов записей, и запрос возвращает 1877 строк.

Проблема в том, что он возвращает их через 86 секунд, и это время резко меняется, когда я изменяю литерал «20110825» на более старые значения.

Например, если я поставлю '20110725', запрос вернет 3483 строки за 35 миллисекунд.

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

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

  • 50%: поиск по индексу в tableA.field2 (это кластеризованный индекс только для этого поля)
  • 50%: поиск индекса по tableB.field1 (неуникальный, некластеризованный индекс только для этого поля)
  • 0%: присоединиться

Когда это почти мгновенно, план выполнения показывает:

  • 98%: поиск индекса по tableA.field1 (неуникальный, некластеризованный индекс только для этого поля)
  • 2%: поиск индекса по tableB.field1 (неуникальный, некластеризованный индекс только для этого поля)
  • 0%: присоединиться

Так что мне кажется, что решение оптимизатора использовать кластерный индекс для tableA.field2 не оптимально.

Есть ли недостаток в дизайне базы данных? В запросе SQL?

Могу ли я каким-либо образом заставить базу данных использовать правильный план выполнения?

1 Ответ

3 голосов
/ 05 сентября 2011

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

Предположительно, когда они в последний раз обновлялись, было мало или не было строк, соответствующих критериям '20110825', и SQL Server использует стратегию объединения, основанную на этом предположении.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...