2012-03-01 48 views
2

我已經使用DataContext.CreateDatabase創建了一個數據庫並在其中插入了記錄。在c#中的數據庫中通過id查找記錄的最快方法是什麼?

有很多的在它的記錄,所以我想找到一個記錄由它的最快的方法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

無論您正在搜索的(定期)需要在數據庫中具有最佳的速度上定義的索引。請注意,某些列和某些類型的搜索不能很好地進行索引(例如,大型文本字段或「包含」搜索),並且可能需要不同類型的索引(全文)。就你而言,看起來你正在使用主鍵,它應該有一個聚集索引。

一旦你定義的索引(ES),你再要執行走索引的優勢查詢。第一個查詢執行全表掃描,將所有結果加載到內存中,然後在代碼中遍歷它們。您尚未給數據庫任何機會來幫助您加速查詢,並且傳輸的數據量遠遠超過您的需求。第二個查詢允許數據庫通過添加指定索引列的where子句來使用索引來查找您感興趣的行。如果單獨進行(即,您只查找這一行,而不是按順序查找每行),那麼它是最優的。它爲該行執行索引查找,然後將該行傳輸到應用程序。

如果它實際上是主鍵,那麼可以通過使用SingleOrDefault來提高可讀性,儘管不是性能,因爲表中只能有一行包含該鍵。如果您有一列您希望是唯一但不是主鍵的列,那麼強化查詢的單一性也將有助於檢測潛在錯誤,但不會在主鍵上下文中檢測到。在這種情況下,如果找到多個結果,則SingleOrDefault將引發異常,而FirstOrDefault將僅僅選擇集合中的第一個,而不會提供有關不一致的任何信息。

1

你的第二個代碼示例應該做到這一點

2

第二個得到更快的最快的方法,因爲它會產生一個WHERE子句,查詢數據庫,僅返回匹配的行到你的應用程序時,像WHERE ID = <whatever>

第一個是緩慢的,因爲它遍佈讀取來自城市數據庫表中,並將它們複製每一條記錄到你的應用程序,它丟棄所有,但他們中的一個。

如果您還沒有一個已經,在城市表的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(); 
    } 
} 
相關問題