在c#中,按id在数据库中查找记录的最快方法是什么
本文关键字:方法 是什么 数据库 id 查找记录 | 更新日期: 2023-09-27 18:26:24
我使用DataContext.CreateDatabase创建了一个数据库,并在其中插入了记录。
里面有很多记录,所以我想以最快的方式通过它的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();
而且速度更快。
有更好更快的方法吗?
无论你(定期)搜索什么,都需要在数据库中定义一个索引,以获得最佳速度。请注意,某些列和某些类型的搜索不能很好地索引(例如,大文本字段或"包含"搜索),可能需要不同类型的索引(全文)。在您的情况下,您似乎正在使用主键,主键上应该有一个聚集索引
一旦定义了索引,就需要执行利用索引的查询。第一个查询执行完整的表扫描,将所有结果加载到内存中,然后在代码中迭代。您没有给数据库任何机会来帮助您加快查询速度,并且传输的数据比您需要的多得多。第二个查询允许数据库使用索引,通过添加指定索引列的where子句,只查找您感兴趣的行。如果是孤立地进行的(即,您只查找这一行,而不是按顺序查找每一行),那么它是最优的。它对该行执行索引查找,然后仅将该行传输到应用程序。
如果它实际上是主键,那么您可以通过使用SingleOrDefault
来提高可读性,但不能提高性能,因为表中只能有一行具有该键。强制查询的单一性也将有助于检测潜在的错误,尽管不是在主键的上下文中,如果您有一个期望唯一但不是唯一的列。在这种情况下,如果找到多个结果,SingleOrDefault
将抛出异常,而FirstOrDefault
只会选择集合中的第一个结果,而不会向您提供任何关于不一致性的信息。
第二个更快,因为它在查询数据库时生成了一个where子句,类似于WHERE ID = <whatever>
,它只向应用程序返回匹配的行。
第一个很慢,因为它从数据库中的Cities表中读取每一条记录,并将它们全部复制到应用程序中,而应用程序会丢弃除一条之外的所有记录。
如果您还没有,那么在Cities表的ID列上创建索引(或者更可能是主键)会使速度更快,尤其是在向表中添加更多数据时。
您的第二个代码示例应该是实现的最快方法
linq语句是最好的。在后台,它必须将linq语句和firstorddefault转换为SQL服务器的语句。在检索结果时,它将其映射到一个城市对象中。
因此,它实际上是以类似于这个预先准备好的声明的形式发送的:
SELECT TOP 1 * FROM Cities where ID=@ID
理论上,你可以通过如下方式自己发送准备好的声明来加快速度,但它不会给你城市对象,在大多数情况下也不会明显更快:(让我重复,这不太可能是你想做的,但这是一种更快的获取数据的方式)
string commandText = "SELECT TOP 1 * FROM Cities where ID=@ID;";
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();
}
}