9

更新:クエリはタイムアウトをスローしないようです。接続がタイムアウトしています。

これは、クエリを実行するためのサンプル コードです。時間のかかるクエリの実行中に、タイムアウト例外がスローされることがあります。

これらの手法は使用できません: 1) タイムアウトを増やします。2) コールバックを使用して非同期で実行します。これは同期的に実行する必要があります。

時間のかかるクエリの実行中に接続を維持するための他のテクニックを提案してください。

private static void CreateCommand(string queryString,
    string connectionString)
{
    using (SqlConnection connection = new SqlConnection(
               connectionString))
    {
        SqlCommand command = new SqlCommand(queryString, connection);
        command.Connection.Open();
        command.ExecuteNonQuery();
    }
}
4

16 に答える 16

17

行を返さない ExecuteNonQuery を使用しているため、このポーリング ベースのアプローチを試すことができます。非同期の方法で (コールバックなしで) クエリを実行しますが、アプリケーションはクエリが完了するまで (while ループ内で) 待機します。MSDNから。これにより、タイムアウトの問題が解決するはずです。ぜひお試しください。

しかし、クエリを最適化して 30 秒未満で実行することについてもっと考えるべきだという意見に同意します。

        IAsyncResult result = command.BeginExecuteNonQuery();

        int count = 0;
        while (!result.IsCompleted)
        {
            Console.WriteLine("Waiting ({0})", count++);
            System.Threading.Thread.Sleep(1000);
        }
        Console.WriteLine("Command complete. Affected {0} rows.",
        command.EndExecuteNonQuery(result));
于 2008-09-19T22:33:24.447 に答える
4

最初にクエリをチェックして、クエリが最適化されているかどうか、欠落しているインデックスで何らかの形で実行されていないかどうかを確認する必要があります。大規模なデータベースであっても、適切に調整されていれば、ほとんどのクエリに 30 秒が割り当てられます。クエリプランを使用して、クエリをそれよりも速く実行できないという確固たる証拠がある場合は、タイムアウトを増やす必要があります。接続を維持する方法は他にありません。クエリはその時間内に完了しません。

于 2008-09-19T21:33:46.490 に答える
1

これは醜いハックですが、実際の問題を修正できるようになるまで、一時的に問題を解決するのに役立つ場合があります

    private static void CreateCommand(string queryString,string connectionString)
    {
        int maxRetries = 3;
        int retries = 0;
        while(true)
        {
            try
            {
                using (SqlConnection connection = new SqlConnection(connectionString))
                {
                    SqlCommand command = new SqlCommand(queryString, connection);
                    command.Connection.Open();
                    command.ExecuteNonQuery();
                }
                break;
            }
            catch (SqlException se)
            {
                if (se.Message.IndexOf("Timeout", StringComparison.InvariantCultureIgnoreCase) == -1)
                    throw; //not a timeout

                if (retries >= maxRetries)
                    throw new Exception( String.Format("Timedout {0} Times", retries),se);

                //or break to throw no error

                retries++;
            }
        }
    }
于 2009-05-09T14:16:10.433 に答える
1

データ アクセス API の機能を使用してクエリを 30 秒以上実行することが禁止されている場合は、SQL を確認する必要があります。

ADO.NET の使用を最適化することによって得られるパフォーマンスの向上は、SQL の最適化による向上と比較するとわずかです。

そして、SQL を実行する最も効率的な方法をすでに使用しています。他の手法は気が遠くなるほど遅くなります (ただし、DataSet を使用して行をすばやく取得し、クライアント側の処理が非常に遅い場合は、最初の取得を 30 秒未満に短縮できる可能性がありますが、私はそれを疑っています. )

挿入を行っているかどうかがわかっている場合は、一括挿入を使用する必要があります。しかし、あなたのSQLの内容はわかりません。

于 2009-05-06T02:49:44.857 に答える
1

私はテラピンに同意しなければなりません。

時間を短縮する方法にはいくつかのオプションがあります。まず、あなたの会社で DBA を採用している場合は、DBA に提案を求めることをお勧めします。

それができない場合、または最初に他のことを試してみたい場合は、次の 3 つの主要なオプションがあります。

  1. タイムアウトで実行されるコンポーネントにクエリを分割します。これはおそらく最も簡単です。
  2. クエリを変更して、データベースを介したアクセス パスを最適化します (一般的には、インデックスにできるだけ近づけます)。
  3. インデックスを変更または追加して、クエリのアクセス パスに影響を与えます。
于 2008-09-19T21:28:09.703 に答える
1

タイムアウト値を変更するデフォルトのプロセスを使用できない場合は、おそらくさらに多くの作業を行う必要があります。次のオプションが思い浮かびます

  1. DBA および別のコード レビューで、クエリを可能な限り最適化したことを検証します。
  2. 基礎となる DB 構造に取り組み、DB 側で得られる利益があるかどうかを確認し、idex を作成/変更します。
  3. 別のパラメーターを呼び出すだけの複数の戻りパラメーターを持つプロシージャーを実行することを意味する場合でも、それを複数の部分に分割します。(このオプションは洗練されたものではありません。正直なところ、コードにこれだけの時間がかかる場合は、管理者に連絡して 30 秒のタイムアウトについて再検討する必要があります)
于 2008-09-19T21:34:35.880 に答える
1

最近、SQL Server 2000 データベースで同様の問題が発生しました。

クエリ中に、db サーバーの master データベースで次のクエリを実行し、トラブルシューティングが必要なロックがあるかどうかを確認します。

select 
  spid,
  db_name(sp.dbid) as DBname,
  blocked as BlockedBy,
  waittime as WaitInMs,
  lastwaittype,
  waitresource,
  cpu,
  physical_io,
  memusage,
  loginame,
  login_time,
  last_batch,
  hostname,
  sql_handle
from sysprocesses sp
where (waittype > 0 and spid > 49) or spid in (select blocked from sysprocesses where blocked > 0)

SQL Server Management Studio 2008 には、クエリ中にデータベースの状態を確認できる非常に優れたアクティビティ モニターも含まれています。

私たちの場合、データベースをビジー状態に保つのは networkio ロックでした。結果セットを十分に迅速に切断しなかったのは、一部のレガシー VB コードでした。

于 2008-09-19T22:23:04.750 に答える
0

クエリをいくつかの小さなチャンクに分割することを考えましたか?

また、次の場所でDatabase EngineTuningAdvisorに対してクエリを実行しましたか。

ManagementStudio>ツール>データベースエンジンチューニングアドバイザー

最後に、クエリ自体を確認できますか?

乾杯

于 2009-05-12T01:55:12.073 に答える
0

結果のページングを試してみる価値があるかもしれません。

于 2009-10-30T18:05:59.480 に答える
0

SQL をストアド プロシージャ内にラップしようとしたことがありますが、メモリ管理が優れているようです。従来の ADO を使用した内部クエリを含む plan sql ステートメントで、このようなタイムアウトが発生したことがあります。つまり、select * from (select ....) t inner join somthingTable です。内部クエリが非常に多くの結果を返していた場所。

その他のヒント 1. with(nolock) 実行ヒントを使用して読み取りを実行すると、ダーティであり、お勧めしませんが、高速になる傾向があります。2. また、実行しようとしている SQL の実行計画を確認し、行スキャン (テーブルを結合する順序) を減らします。3. 読み取りを高速化するために、テーブルにいくつかのインデックスを追加することを検討してください。4. 行の削除には非常にコストがかかることもわかりました。呼び出しごとの行数を制限してみてください。5. @table 変数を #temporary テーブルと交換することも、以前はうまくいきました。6. また、不適切な実行計画を保存した可能性もあります (聞いたことがない、見たことがない)。

お役に立てれば

于 2009-05-12T06:27:14.907 に答える
0

タイムアウト期間内にそれぞれが実行される複数のチャンクにクエリを分割する必要があります。

于 2008-09-19T21:20:21.657 に答える
0
command.CommandTimeout *= 2;

これにより、デフォルトのタイムアウトである 30 秒が 2 倍になります。

または、構成ファイルに CommandTimeout の値を入れて、再コンパイルせずに必要に応じて調整できるようにします。

于 2008-09-19T21:11:24.500 に答える
0

更新:クエリはタイムアウトをスローしないようです。接続がタイムアウトしています。

えっ、クエリを実行しなくても接続がタイムアウトするの?接続とクエリの 2 つのタイムアウトがあるためです。誰もがクエリに集中しているようですが、接続タイムアウトが発生した場合、それはネットワークの問題であり、クエリとは何の関係もありません。クエリを実行するには、まず接続を確立する必要があります。

于 2009-05-12T15:33:03.003 に答える
0

どうしてもタイムアウトを増やすことができない場合、唯一のオプションは、クエリの実行時間をデフォルトの 30 秒のタイムアウト内に短縮することです。

于 2008-09-19T21:12:57.417 に答える
0

接続/コマンドのタイムアウトを増やすことは嫌いです

于 2008-09-19T22:24:31.580 に答える