9

どちらが速いでしょう。

1)データリーダーをループし、入力されたデータテーブルに基づいてカスタムの行と列を作成する

2)または、dataAdapterオブジェクトを作成し、データテーブルを(.Fill)だけ入力します。

データテーブルを動的に作成しても、データリーダーのパフォーマンスは維持されますか?

4

9 に答える 9

12

DataAdapterは内部でDataReaderを使用するため、経験は同じである可能性があります。

DataAdapterの利点は、メンテナンスが必要な多くのコードを切り取ることができることです。

この議論は少し宗教的な問題なので、間違いなく周りを見回して、自分の状況に最適なものを決定してください。

于 2008-12-02T16:53:43.203 に答える
11

実際にすべてのデータをデータベースから取得する必要があると仮定すると、データベースとネットワークでかかる時間は、インプロセスでデータ構造をメモリに入力するのにかかる時間よりも確実に小さくなります。

はい、場合によっては、DataReader を使用することで少し節約できる場合があります。特に、データをストリーミングしたい場合は便利かもしれませんが、実際にすべてが必要な場合は、最も単純なコードを使用します。DataSet の人口が重大なパフォーマンスの問題を引き起こしていると思われる場合は、それをプロファイリングしてから改善を試みてください。

于 2008-12-02T17:05:51.620 に答える
8

オプション#1は遅くなります。ただし、手動でカスタム行を追加するよりも、datareader をデータテーブルに変換するためのより良い方法があります。

DataTable dt = new DataTable();

using (SqlConnection conn = GetOpenSqlConnection())
using (SqlCommand cmd = new SqlCommand("SQL Query here", conn)
using (IDataReader rdr = cmd.ExecuteReader())
{
    dt.Load(rdr);
}

これと using の違いについてはコメントできません.Fill()

于 2008-12-02T16:58:08.780 に答える
3

データテーブル自体を埋めることについて話すことはできませんが、データリーダーを使用するのが最も効率的な読み取り方法です。

于 2008-12-02T16:57:09.157 に答える
2

データリーダーの方が高速です。また、2.0 以降を使用している場合は、おそらくデータテーブルを使用する必要さえありません。オブジェクトの汎用リストを使用できます。

于 2008-12-02T17:04:01.110 に答える
1

たとえば、データの読み込みの進行状況を表示する必要がある場合は、DataReader があると便利です。DataSet では、データのロード中に何かを行うことはできません。

一方、DataSet はオールインワン オブジェクトです。そのため、DataSet は非常に遅くなります。DataReader は、データ操作が非常に遅いコード内の場所で追加のブーストを提供できます。これらの場所で、DataSet から DataReader に変更します。DataReader はメモリ内のスペースも少なくて済みます。

もちろん、優れた DataReader をコーディングするには時間がかかりますが、それだけの価値はあります。たとえば、データベースから取得した画像や音楽で遊ぶ場合。

このトピックの詳細については、MSDN マガジンをご覧ください

于 2008-12-02T16:58:44.847 に答える
1

このような多くの質問と同様に、答えは次のとおりです。

前もってデータの構造がわからず、その場で TableAdapter を作成している場合は、動的 DataTable の方が効率的です。TableAdapter の作成には、大量のコード生成が必要です。

ただし、データの構造を前もって知っている場合は、「どのくらいの機能が必要ですか?」という質問になります。

完全な CRUD 実装が必要な場合は、すべての CRUD コードを自分で作成するよりも、TableAdapter を使用する方が効率が向上します。また、TableAdapter の実装は問題ありません (あまり良くありません)。より効率的なものが必要な場合は、nHibernate やその他の ORM を使用することをお勧めします。

完全な CRUD 実装を必要とせず (つまり、これは読み取り専用ソリューションです)、データ構造を前もって知っている場合は、動的に生成された DataTable に対して TableAdapter 読み取り専用実装の効率をテストする必要があります。 . 私が賭け屋だったら、データを 1 回バインドして複数回読み取るため、TableAdapter の実装にお金をかけます。

于 2008-12-02T17:10:48.630 に答える
1

接続時にレコードが読み取られるとすぐにレコードを取得できるように、順方向のみ、一度に 1 行ずつデータを読み取るアプローチであるDataReader'sを使用すると、メモリとパフォーマンスが最適になります。Read

とはいえ、2 つのアプローチの間ではIDataAdapter.FillDataTable.Load. もちろん、それは実装に依存します..ここに私が投稿した2つの間のベンチマークがあります:

public DataTable Read1<T>(string query) where T : IDbConnection, new()
{
    using (var conn = new T())
    {
        using (var cmd = conn.CreateCommand())
        {
            cmd.CommandText = query;
            cmd.Connection.ConnectionString = _connectionString;
            cmd.Connection.Open();
            var table = new DataTable();
            table.Load(cmd.ExecuteReader());
            return table;
        }
    }
}

public DataTable Read2<S, T>(string query) where S : IDbConnection, new() 
                                           where T : IDbDataAdapter, IDisposable, new()
{
    using (var conn = new S())
    {
        using (var da = new T())
        {
            using (da.SelectCommand = conn.CreateCommand())
            {
                da.SelectCommand.CommandText = query;
                da.SelectCommand.Connection.ConnectionString = _connectionString;
                DataSet ds = new DataSet(); //conn is opened by dataadapter
                da.Fill(ds);
                return ds.Tables[0];
            }
        }
    }
}

2 番目のアプローチは常に最初のアプローチよりも優れていました。

Stopwatch sw = Stopwatch.StartNew();
DataTable dt = null;
for (int i = 0; i < 100; i++)
{
    dt = Read1<MySqlConnection>(query); // ~9800ms
    dt = Read2<MySqlConnection, MySqlDataAdapter>(query); // ~2300ms

    dt = Read1<SQLiteConnection>(query); // ~4000ms
    dt = Read2<SQLiteConnection, SQLiteDataAdapter>(query); // ~2000ms

    dt = Read1<SqlCeConnection>(query); // ~5700ms
    dt = Read2<SqlCeConnection, SqlCeDataAdapter>(query); // ~5700ms

    dt = Read1<SqlConnection>(query); // ~850ms
    dt = Read2<SqlConnection, SqlDataAdapter>(query); // ~600ms

    dt = Read1<VistaDBConnection>(query); // ~3900ms
    dt = Read2<VistaDBConnection, VistaDBDataAdapter>(query); // ~3700ms
}
sw.Stop();
MessageBox.Show(sw.Elapsed.TotalMilliseconds.ToString());

Read1見た目は良くなりますが、データ アダプターのパフォーマンスは向上します (1 つのデータベースが他のデータベースより優れていることを混同しないように、クエリはすべて異なっていました)。ただし、2つの違いはクエリに依存していました。その理由は、行を追加するときにドキュメントからLoad行ごとにさまざまな制約をチェックする必要があるためです (メソッド on )が、そのためだけに設計された DataAdapters にある場合 - DataTables の高速作成。DataTableFill

于 2013-02-14T07:10:18.677 に答える