在SQL Server中选择整个表的最快方法是什么?

时间:2011-03-10 13:18:22

标签: c# .net sql sql-server-2008

我正在编写一个应用程序,它读取整个表,进行一些处理,然后将结果数据写入另一个表。我正在使用SqlBulkCopy类(.net版本的“bcp in”),它可以非常快速地插入。但我首先找不到任何有效的方法来选择数据。没有.net等效的“bcp out”,这对我来说很奇怪。

目前我正在使用select * from table_name。对于预期,选择6,000行需要2.5秒......并且只需600毫秒即可批量插入相同数量的行。

我希望选择数据总是比插入更快。 选择所有行的最快方法是什么?表中的列?


qeustions的答案:

  • 我选择时间为2.5秒2。首先是在运行我的应用程序并运行sql跟踪时。第二个是在SSMS中运行相同的查询。两人都恢复了相同的结果。
  • 我正在使用SqlDataReader读取数据。
  • 没有其他应用程序正在使用此数据库。
  • 我目前的处理时间不到1秒,因此2秒以上的读取时间相对较长。但是,在将其扩展到100,000行和数百万行时,我主要担心(感兴趣)性能。
  • Sql Server 08r2和我的应用程序都在我的开发机器上运行。
  • 一些数据处理是基于设置的,所以我需要将整个表放在内存中(为了支持更大的数据集,我知道这一步可能需要转移到SQL中,所以我只需要在每行操作存储器)

这是我的代码:

DataTable staging = new DataTable();
using (SqlConnection dwConn = (SqlConnection)SqlConnectionManager.Instance.GetDefaultConnection())
{
    dwConn.Open();
    SqlCommand cmd = dwConn.CreateCommand();
    cmd.CommandText = "select * from staging_table";

    SqlDataReader reader = cmd.ExecuteReader();
    staging.Load(reader);
}

3 个答案:

答案 0 :(得分:11)

select * from table_name 是阅读整个表格的最简单,最简单,最快捷的方法。

让我解释为什么你的结果导致错误的结论。

  1. 复制整个表是一种优化的操作,只需要将旧的二进制数据克隆到新的二进制数据中(根据存储机制,最多可以执行文件复制操作)。
  2. 写缓存。 DBMS说记录是写的,但它实际上还没有完成,除非你处理事务。磁盘操作通常会延迟。
  3. 查询表还需要(与克隆不同)将数据从二进制存储的布局/格式调整为最终可由客户端读取的驱动程序相关格式。这需要时间。

答案 1 :(得分:2)

这完全取决于您的硬件,但您的网络很可能是这里的瓶颈。

除了将查询限制为只读取您实际使用的列之外,执行选择的速度与获取的速度一样快。这里涉及缓存,当你连续两次执行它时,第二次会更快,因为数据被缓存在内存中。执行dbcc dropcleanbuffers以检查缓存的效果。

如果你想尽可能快地尝试实现在T-SQL中进行处理的代码,那么它可以直接在服务器上的数据上运行。

速度调整的另一个好方法是在一个磁盘上查看表(查看文件组)和在另一个磁盘上写入的表。这样一个磁盘可以连续读取,另一个磁盘可以连续写入。如果两个操作都发生在同一个磁盘上,则磁盘的磁头会不断地来回转换,严重降低了性能。

如果您的写作逻辑不能用于T-SQL,您还可以查看SQL CLR。

另一个提示:当您从表中选择*时,如果可能,请使用datareader。这样你就不会首先在内存中实现整个事物。

GJ

答案 2 :(得分:1)

一般来说,将列名包含在选择列表中是一个好主意,但是对于今天的RDBMS,它不会有太大的区别。如果限制所选列,您将只看到这方面的差异。一般来说,最好包括列名。但回答它似乎确实比插入你描述的场景慢 是的,select * from table_name确实是从表中读取所有行和列的最快方法