SQL Server простой Вставить выписки
У меня есть простая таблица с 6 столбцами. В большинстве случаев любые вставные инструкции для него работают очень хорошо, но время от времени я получаю исключение таймаута БД:
Время ожидания истекло. Период ожидания истекает до завершения операции или сервер не отвечает. Заявление завершено.
Время ожидания установлено на 10 секунд.
Я должен упомянуть, что я использую NHibernate и что оператор также включает "select SCOPE_IDENTITY()" сразу после самой вставки.
Моя мысль заключалась в том, что таблица была заблокирована или что-то в этом роде, но в то время в этой таблице не было никаких других операторов.
Все вставки очень просты, все выглядит нормально в sql-профилировщике, таблица не имеет индексов, а PK (заполнение страницы: 98.57%).
Любые идеи о том, что я должен искать?
Спасибо.
Ответы
Ответ 1
В нашем QA были некоторые подключения Excel, которые возвращали большие результирующие наборы, эти запросы были приостановлены с WaitType ASYNC_NETWORK_IO в течение некоторого времени. За это время все остальные запросы были исчерпаны, поэтому конкретная вставка не имела к этому никакого отношения.
Ответ 2
Я думаю, что ваш самый вероятный виновник является блокирующим блокированием от другой транзакции (или, может быть, от триггера или чего-то еще за кулисами).
Самый простой способ сказать, это запустить INSERT
, а пока он висел, запустите EXEC SP_WHO2
в другом окне на том же сервере. В этом списке будет отображаться все текущее действие базы данных и есть столбец с именем BLK
, который покажет вам, заблокированы ли какие-либо процессы. Проверьте SPID
вашего висячего соединения, чтобы узнать, есть ли что-нибудь в столбце BLK
, и если да, то процесс, который блокирует вас.
Даже если вы не думаете, что есть какие-либо другие запущенные операторы, единственный способ узнать наверняка - перечислить текущие транзакции с использованием SP, как этот.
Ответ 3
Этот вопрос кажется хорошим местом для фрагмента кода, который я использовал для просмотра фактического текста SQL заблокированных и блокирующих запросов.
В приведенном ниже фрагменте используется соглашение, которое SP_WHO2
возвращает "." текст для BlockedBy
для незаблокированных запросов, и поэтому он отфильтровывает их и возвращает текст SQL оставшихся запросов (как "жертва", так и "виновник" ):
--prepare a table so that we can filter out sp_who2 results
DECLARE @who TABLE(BlockedId INT,
Status VARCHAR(MAX),
LOGIN VARCHAR(MAX),
HostName VARCHAR(MAX),
BlockedById VARCHAR(MAX),
DBName VARCHAR(MAX),
Command VARCHAR(MAX),
CPUTime INT,
DiskIO INT,
LastBatch VARCHAR(MAX),
ProgramName VARCHAR(MAX),
SPID_1 INT,
REQUESTID INT)
INSERT INTO @who EXEC sp_who2
--select the blocked and blocking queries (if any) as SQL text
SELECT
(
SELECT TEXT
FROM sys.dm_exec_sql_text(
(SELECT handle
FROM (
SELECT CAST(sql_handle AS VARBINARY(128)) AS handle
FROM sys.sysprocesses WHERE spid = BlockedId
) query)
)
) AS 'Blocked Query (Victim)',
(
SELECT TEXT
FROM sys.dm_exec_sql_text(
(SELECT handle
FROM (
SELECT CAST(sql_handle AS VARBINARY(128)) AS handle
FROM sys.sysprocesses WHERE spid = BlockedById
) query)
)
) AS 'Blocking Query (Culprit)'
FROM @who
WHERE BlockedById != ' .'
Ответ 4
Может быть, что таблица занимает много времени, чтобы расти.
Если у вас есть таблица, которая будет расти на большую сумму и не будет включена мгновенная инициализация файла, тогда запрос может быть тайм-аут каждый раз в то время.
Проверьте этот беспорядок: MSDN
Ответ 5
никаких других операторов, выполняемых в этой таблице в это время.
Как насчет операторов, работающих с другими таблицами, как часть транзакции? Это может оставить блокировки в таблице проблем.
Также проверяйте, будет ли происходить рост файла журнала или файла данных в то время, если вы используете SQL2005, он будет отображаться в журналах ошибок SQL.
Ответ 6
Посмотрите на фрагментацию таблицы, вы можете получить разбиение страниц из-за этого