2009-05-14 5 views
2

Мы используем C# и Linq2SQL для получения данных из базы данных для некоторых отчетов. В некоторых случаях это занимает некоторое время. Более 30 секунд, что кажется по умолчанию CommandTimeout.C#, Linq2SQL: Как долго должен быть CommandTimeout и где он должен быть установлен?

Итак, я думаю, мне нужно подняться до CommandTimeout. Но вопрос в том, сколько? Плохо ли это просто установить его очень высоко? Было бы плохо, если бы клиент пытался что-то сделать, и только потому, что у него было гораздо больше данных в его базе данных, чем у обычного клиента, он не мог получить свои отчеты из-за тайм-аутов? Но как я могу узнать, сколько времени это может потребоваться? Есть ли способ установить его на бесконечность? Или это считается очень плохой?

И где я должен установить его? У меня есть статический класс базы данных, который генерирует новый datacontext для меня, когда он мне нужен. Могу ли я просто создать константу и установить ее всякий раз, когда я создаю новый datacontext? Или он должен быть установлен на разные значения в зависимости от usecase? Неужели плохо иметь высокий тайм-аут для чего-то, что не займет много времени? Или это не имеет значения?

Слишком высокий ConnectionTimeout может, конечно, быть более раздражающим. Но есть ли случай, когда пользователь/клиент хотел бы что-то тайм-аут? Может ли сервер SQL заморозить, чтобы команда никогда не заканчивалась?

ответ

3

CommandTimeout и т. Д. Действительно должен быть увеличен только на основе конкретных сценариев. Это может привести к непредвиденным длительным блокировкам и т. Д. Сценариев (или, что еще хуже: незаметный сценарий взаимоблокировки). Что касается , то как высокий ... сколько времени занимает запрос? Добавьте некоторый запас высоты, и у вас есть свой ответ.

Другое дело, конечно, в том, чтобы сократить время запроса. Это может означать ручную оптимизацию некоторых TSQL в sproc, как правило, в сочетании с проверкой стратегии индексирования и, возможно, большими изменениями, такими как денормализация или другие изменения схемы. Это может также включать в себя стратегию хранения данных, поэтому вы можете переносить нагрузку на отдельную базу данных (вдали от транзакционных данных), с оптимизированной для отчетности схемой. Может быть, звезда-схема.

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

Да, SQL Server может замерзнуть, чтобы команда никогда не заканчивалась. Открытая блокирующая транзакция будет самой простой ... получите два, и вы можете зайти в тупик. Обычно система обнаруживает локальный тупик - но не всегда, особенно если задействован DTC (т. Е. Нелокальные блокировки).

+0

Как проверить стратегию индексирования? Думаю, в настоящее время нет добавленных индексов, но как я могу увидеть, где их добавить? (Первичные ключи уже проиндексированы?) – Svish

0

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

0

Первичные ключи по умолчанию имеют кластерный индекс. Я нашел следующий сценарий (я думаю, что это было на MSDN), который будет генерировать код для создания какой-либо сервер индексов SQL думает, будет полезным (DEF работает на SQL2008, я думаю, что это было введено в 2005 году):

SELECT 

    migs.avg_total_user_cost * (migs.avg_user_impact/100.0) * (migs.user_seeks + migs.user_scans) AS improvement_measure, 

    'CREATE INDEX [missing_index_' + CONVERT (varchar, mig.index_group_handle) + '_' + CONVERT (varchar, mid.index_handle) 

    + '_' + LEFT (PARSENAME(mid.statement, 1), 32) + ']' 

    + ' ON ' + mid.statement 

    + ' (' + ISNULL (mid.equality_columns,'') 

    + CASE WHEN mid.equality_columns IS NOT NULL AND mid.inequality_columns IS NOT NULL THEN ',' ELSE '' END 

    + ISNULL (mid.inequality_columns, '') 

    + ')' 

    + ISNULL (' INCLUDE (' + mid.included_columns + ')', '') AS create_index_statement, 

    migs.*, mid.database_id, mid.[object_id] 

FROM sys.dm_db_missing_index_groups mig 

INNER JOIN sys.dm_db_missing_index_group_stats migs ON migs.group_handle = mig.index_group_handle 

INNER JOIN sys.dm_db_missing_index_details mid ON mig.index_handle = mid.index_handle 

WHERE migs.avg_total_user_cost * (migs.avg_user_impact/100.0) * (migs.user_seeks + migs.user_scans) > 10 

ORDER BY migs.avg_total_user_cost * migs.avg_user_impact * (migs.user_seeks + migs.user_scans) DESC 
+0

Считаете ли вы, что это может быть чрезмерным для того, что можно отредактировать вручную? – Xander

0
//If you have an AseCommand object instance.... 
AseCommand _AseCommand = new AseCommand("procedure_test"); 

//You can set up the timeout infinite as follows 
_AseCommand.CommandTimeout = System.Threading.Timeout.Infinite; 
Смежные вопросы