Microsoft SQL Server: как повысить производительность глупого запроса? - PullRequest
0 голосов
/ 10 февраля 2011

Меня попросили помочь с проблемой производительности установки сервера SQL. Я не эксперт по SQL Server, но я решил взглянуть. Мы используем приложение с закрытым исходным кодом, которое работает нормально. Однако после обновления SQL Server с 2000 по 2005 г. производительность приложений, как сообщается, значительно снизилась. Я запустил SQL-профилировщик и перехватил следующий запрос (имена полей были изменены, чтобы защитить невинных), который занял около 30 секунд. Первой моей мыслью было оптимизировать запрос. Но это невозможно, учитывая, что приложение является закрытым исходным кодом, а поставщик не является полезным. Поэтому я ушел, пытаясь выяснить, как сделать этот запрос быстрым, не меняя его. Мне также не ясно, как этот запрос выполнялся быстрее на более старом продукте SQL Server 2000. Возможно, для этого экземпляра была применена какая-то настройка производительности, которая не переносилась или не работает на новом сервере SQL. На ум приходит DBCC PINTABLE.

В любом случае, вот неправильный запрос:

select min(row_id) from Table1 where calendar_id = 'Test1' 
and exists 
    (select id from Table1 where calendar_id = 'Test1' and
         DATEDIFF(day, '12/30/2010 09:21', start_datetime) = 0
     ) 
and exists 
    (select id from Table1 where calendar_id = 'Test1' and
         DATEDIFF(day, end_datetime, '01/17/2011 09:03') = 0
     );  

Таблица 1 имеет около 6200 записей и выглядит следующим образом. Я пытался создать различные индексы безрезультатно.

id                 calendar_id  start_datetime  end_datetime
int, primary key   varchar(10)  datetime        datetime
1                  Test1        2005-01-01...   2005-01-01...
2                  Test1        2005-01-02...   2005-01-02...
3                  Test1        2005-01-03...   2005-01-03...
...

Я был бы очень признателен, если бы кто-нибудь мог помочь разгадать эту тайну.

Заранее спасибо.

Ответы [ 4 ]

2 голосов
/ 10 февраля 2011

Единственное, что должно помочь, - это индекс покрытия для calendar_id:

create index <indexname> 
    on table (calendar_id, id) 
    include (start_datetime, end_datetime);

Это удовлетворит предикаты calendar_id = 'Test1', сортировку min(row_id) и предоставит материал для оценки не-SARG-able DATEFIFF предикаты.Если в таблице нет других столбцов, то это, вероятно, тот кластерный индекс, который вам нужен, и первичный ключ id должен быть некластеризованным.

1 голос
/ 10 февраля 2011

Проверьте различия между планом выполнения на старом сервере sql и новом.http://www.sql -server-performance.com / советы / query_execution_plan_analysis_p1.aspx

1 голос
/ 10 февраля 2011

Убедитесь, что индексы сделали преобразование.Затем обновите статистику.

0 голосов
/ 10 февраля 2011

Еще одна единственная вещь, которую вы можете сделать, помимо предложенного Remus Rusanu индекса, - это обновление до версии Enterprise, которая имеет более продвинутую функцию сканирования (как в SQL Server 2005, так и в версии 2008 Enterprise Edition), которая позволяет нескольким задачам совместно использовать полную таблицу сканирование.

Кроме того, я не думаю, что вы можете что-то сделать, если не можете изменить запрос. Причина в том, что запрос выполняет сравнение с результатом функции в предложении Where. Это означает, что он заставит SQL Server выполнять сканирование таблицы Table1 при каждом его выполнении.

Чтение страниц (дополнительная информация о расширенном сканировании)

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