ADO.NET / EF から SQL Server を叩いていると、「タイムアウト期限が過ぎました」系の例外が出る。接続の待ち切れと、コマンド実行の待ち切れは別物なので、まずどちらなのかを分ける。
先に結論
- 接続タイムアウト … サーバに繋がる前に切れる(ネットワーク・インスタンス停止・接続上限)
- コマンドタイムアウト … 繋がったあと、文の実行が設定秒数を超える(遅延・ブロッキング・悪い計画)
- 秒数を延ばす前に「遅い理由」を見る。延ばすだけだと再発しやすい
- 例外メッセージと接続文字列/コマンドの Timeout 設定を突き合わせる
切り分けの順序
- 例外文面が「接続」寄りか「実行」寄りかを読む
- 同じ操作が SSMS 直実行でも遅いか(アプリだけならプールやパラメータ計画を疑う)
- ブロッキングしていないか(誰かがロック保持)を確認
- 実行計画がインデックスを使えているか、スキャン過多でないかを見る
- 統計情報の古さ・パラメータスニッフィングも候補
よくある原因
- ロック待ち(別セッションが長く保持)
- フルスキャンやネストループ過多の重い計画
- 大きな一括更新・夜間バッチとの競合
- 接続文字列の Connect Timeout が短い/サーバ負荷で受けられない
- EF の既定コマンド秒数(よく 30 秒)を超える処理
関連: デッドロック概要 / 実行計画とインデックス未使用
対策の型
- 遅い文を特定し、索引・条件・取得列を見直す
- トランザクションを短く、必要行だけ触る
- コマンド秒数は「上限の安全網」。根本対策とセットで触る
- 接続側ならネットワーク経路・インスタンス稼働・接続数を先に見る
- 失敗時ログに「操作名・経過目安・接続/コマンドのどちら」を残す
ざっくりまとめ
- 接続切れと実行切れを分ける
- 延長より遅さの原因(ロック・計画・統計)
- ブロッキングと実行計画が次の調べどころ
関連記事