2012-03-01 16 views
2

DataContext.CreateDatabaseを使用してデータベースを作成し、レコードを挿入しました。データベースのIDを使ってC#でレコードを見つける最速の方法は何ですか?

そこにはたくさんのレコードがあるので、私はそのレコードのIDをもっとも速い方法で見つけたいと思っています。

は、まず私が試した:

foreach (var currentRecord in _context.Cities) 
{ 
    if (currentRecord.ID == recordIdToFind) 
    return currentRecord; 
} 

が、それは非常に遅かったので、私はそれを変更:

var recordToReturn = from r in _context.Cities 
        where r.ID == recordIdToFind 
        select r; 
return recordToReturn.FirstOrDefault(); 

、より速くそれを得ました。

もっと速い方法がありますか?

答えて

2

あなたが検索しているもの(定期的に)は、最適な速度のためにデータベース内にインデックスが定義されている必要があります。一部の列や特定の種類の検索では索引が正しく作成されない(大きなテキスト・フィールドや「contains」検索など)、索引(フルテキスト)が必要な場合があります。あなたのケースでは、主キーを使用しているように見えます。プライマリキーにはクラスタードインデックスが必要です。

インデックスが定義されたら、インデックスを利用するクエリを実行する必要があります。最初のクエリは、フルテーブルスキャンを実行し、すべての結果をメモリにロードし、コード内で繰り返し処理します。クエリを高速化し、必要以上に多くのデータを転送するのに役立つ機会をデータベースに与えていません。 2番目の問合せでは、索引付き列を指定するwhere句を追加することにより、データベースで索引を使用して目的の行のみを検索できます。単独で実行された場合(つまり、すべての行ではなく、この1つの行のみを参照している場合)、最適です。行の索引参照を行い、その行だけをアプリケーションに転送します。

実際にプライマリキーの場合は、テーブルにそのキーを持つ行が1つしかない可能性があるため、パフォーマンスではなく可読性を向上させる可能性があります(SingleOrDefault)。一意であると予想される列があるが、そうでない列がある場合は、主キーのコンテキストではありませんが、クエリの一意性を強制することで潜在的なエラーを検出することもできます。その場合、SingleOrDefaultは複数の結果が見つかった場合に例外をスローしますが、FirstOrDefaultは不一致に関する情報を提供せずにセットの最初のものを選択するだけです。

1

あなたの2番目のコード例では、それはあなたのアプリケーションにのみ一致する行を返しますwhere句、WHERE ID = <whatever>ようなデータベースを照会し、生成するので、二番目が速くなった

2

にこれを行うための最速の方法でなければなりません。

データベースのCitiesテーブルからすべてのレコードを読み取り、それらのすべてをアプリケーションにコピーするため、1つを除いてすべてが破棄されるため、最初の処理は遅いです。

CitiesテーブルのID列のインデックス(または主キー)は、特にテーブルにデータを追加すると、これをさらに高速化します。

0

linq文は、ほぼ同じくらい良いです。フードの下では、linq文とfirstordefaultをSQLサーバへの文に変換する必要があります。結果を取得すると、それを都市オブジェクトにマップします。

だから、実際にはこのプリペアドステートメントに似て何かとして送信されます。

SELECT TOP 1 * FROM Cities where [email protected] 

あなたは理論的には次のように自分自身をプリペアドステートメントを送信することによって、それをスピードアップすることができ、それは都市がオブジェクトあなたを与えるとされていないでしょうほとんどの状況で目に見えないほど速くはありません。(これはやりたいことではありませんが、データを取得する方法はより速いです)

string commandText = "SELECT TOP 1 * FROM Cities where [email protected];"; 

using (SqlConnection connection = new SqlConnection(connectionString)) 
{ 
    SqlCommand command = new SqlCommand(commandText, connection); 
    command.Parameters.Add("@ID", SqlDbType.Int); 
    command.Parameters["@ID"].Value = recordIdToFind; 

    connection.Open(); 
    SqlDataReader reader = command.ExecuteReader(); 
    try 
    { 
     while (reader.Read()) 
     { 
      Console.WriteLine(String.Format("{0}, {1}", 
       reader[0], reader[1])); 
     } 
    } 
    finally 
    { 
     // Always call Close when done reading. 
     reader.Close(); 
    } 
} 
関連する問題