我需要使用C#将SqlServer上的表中的一列字符串加载到内存中的Array中 . 有没有比打开SqlDataReader更快的方法并循环它 . 表很大,时间很关键 .
编辑我正在尝试构建.dll并在服务器上使用它来进行数据库上的某些操作 . 但现在要放慢速度 . 如果这比我重新设计数据库要快 . 我很难有可能有一些解决方案如何加快速度 .
SqlDataReader将是最快的方式 . 通过使用适当的Getxxx方法优化其使用,该方法采用序数作为参数 .
如果速度不够快,请查看是否可以调整查询 . 在要检索的列上放置覆盖索引 . 通过这样做,Sql Server只需读取索引,而不必直接转到表中以检索所需的所有信息 .
Data Reader
关于最快的访问,你将获得SQL与SqlDataReader .
Profile it
值得实际分析您的性能问题 . 通常,在您认为性能问题出现之后,在您对其进行分析后证明是完全错误的 .
例如,它可能是:
时间...查询运行的时间
数据在网络/进程边界上复制所需的时间
时间...... .Net将数据加载到内存中
时间...你的代码需要用它做一些事情
单独分析这些内容可以让您更好地了解瓶颈的位置 . 为了分析您的代码,有一个great article from Microsoft
Cache it
要提高性能,需要考虑的是每次都需要加载所有数据 . 可以缓存列表(或其中的一部分)吗?看一下新的System.Runtime.Caching命名空间 .
Rewrite as T-SQL
如果您正在进行纯粹的数据操作(正如您的问题所示),您可以重写使用数据为T-SQL并在SQL上本机运行的代码 . 这有可能更快,因为您将直接处理数据而不是转移它 .
如果您的代码有很多必要的过程逻辑,您可以尝试将T-SQL与CLR Integration混合,为您提供两个世界的好处 .
这很大程度上归结为逻辑的复杂性(或更多程序性) .
If all else fails
如果所有区域都是最佳的(或接近),并且您的设计没有错误 . 我不会't even get into micro-optimisation, I'只是throw hardware at it .
什么硬件?试试reliability and performance monitor找出瓶颈的位置 . 最有可能解决您描述HDD或RAM的问题 .
如果 SqlDataReader 不够快,也许你应该将你的东西存储在其他地方,比如(内存中)缓存 .
SqlDataReader
不,它实际上不仅是最快的方式 - 它是唯一的(!)方式 . 所有其他机制无论如何都在内部使用DataReader .
我怀疑 SqlDataReader 和你要得到的一样好 .
SqlDataReader是最快的方法 . 确保使用get by序数方法而不是按列名称获取 . 例如GetString的(1);
同样值得的是在连接字符串中试验MinPoolSize,以便池中始终存在一些连接 .
如何将一列行转换为一行列,并且只读取一行? SqlDataReader 有一个读取单行的优化(_1438831_的 System.Data.CommandBehavior.SingleRow 参数),所以也许它可以提高一点速度 .
System.Data.CommandBehavior.SingleRow
我看到了几个优点:
单排改进,
无需在每次迭代时访问数组( reader[0] ),
reader[0]
将数组( reader )克隆到另一个数组可能比循环遍历元素并将每个数组添加到新数组更快 .
reader
另一方面,强制SQL数据库做更多的工作也有一个缺点 .
“提供了一种从SQL Server数据库中读取仅向前行的方法”这是MSDN中SqlDataReader的使用 . SqlDataReder背后的数据结构只允许读取,它被优化用于在一个方向上读取数据 . 在我看来,我想使用SqlDataReader而不是DataSet来进行简单的数据读取 .
你有4套开销 - 磁盘访问 - .net代码(cpu) - SQL服务器代码(cpu) - 在托管代码和非托管代码(cpu)之间切换的时间
首先是
select * where column = “junk”
对你来说足够快,如果不是唯一的解决方案是让磁盘更快 . (您可以比SQL Server更快地从SQL Server获取数据)
您可以在C#中定义Sql Server函数然后运行在列上运行;对不起,我不知道怎么做 . 这可能比数据阅读器更快 .
如果您有多个CPU,并且您知道表中间的值,则可以尝试使用多个线程 .
您可以使用您知道安全的分隔符编写一些TSQL,将所有字符串组合成一个字符串 . 然后在C#中再次拆分字符串 . 这将减少托管代码和非托管代码之间的往返次数 .
一些需要考虑的表面级别的事情可能会影响速度(除了数据阅读器):
数据库查询优化
OrderBy很贵
区别很贵
RowCount很贵
GroupBy很贵
等 . 有时你不能没有这些东西,但如果你能用C#代码处理其中的一些东西,它可能会更快 .
数据库表索引(对于初学者,您的WHERE子句中的字段是否已编入索引?)
数据库表数据类型(在给定数据的情况下,您使用的是最小的吗?)
为什么要将datareader转换为数组?
例如,它是否也可以创建一个您不需要转换为数组的适配器/数据表?
您是否查看了实体框架? (可能会慢一点......但如果你没有选择,可能值得研究一下以确保)
只是随机的想法 . 不确定在你的情况下可能会有什么帮助 .
如果响应是加载大量数据的问题,请查看使用异步方法 - BeginReader .
我一直使用它来在后台填充大的GUI元素,同时应用程序继续响应 .
您还没有确切地说明这些数据有多大,或者为什么要将它们全部加载到数组中 .
通常,对于大量数据,您可能希望将其保留在数据库中或让数据库执行繁重的工作 . 但是我们需要知道你正在做什么样的处理,一次需要一个数组 .
11 回答
SqlDataReader将是最快的方式 . 通过使用适当的Getxxx方法优化其使用,该方法采用序数作为参数 .
如果速度不够快,请查看是否可以调整查询 . 在要检索的列上放置覆盖索引 . 通过这样做,Sql Server只需读取索引,而不必直接转到表中以检索所需的所有信息 .
Data Reader
关于最快的访问,你将获得SQL与SqlDataReader .
Profile it
值得实际分析您的性能问题 . 通常,在您认为性能问题出现之后,在您对其进行分析后证明是完全错误的 .
例如,它可能是:
时间...查询运行的时间
数据在网络/进程边界上复制所需的时间
时间...... .Net将数据加载到内存中
时间...你的代码需要用它做一些事情
单独分析这些内容可以让您更好地了解瓶颈的位置 . 为了分析您的代码,有一个great article from Microsoft
Cache it
要提高性能,需要考虑的是每次都需要加载所有数据 . 可以缓存列表(或其中的一部分)吗?看一下新的System.Runtime.Caching命名空间 .
Rewrite as T-SQL
如果您正在进行纯粹的数据操作(正如您的问题所示),您可以重写使用数据为T-SQL并在SQL上本机运行的代码 . 这有可能更快,因为您将直接处理数据而不是转移它 .
如果您的代码有很多必要的过程逻辑,您可以尝试将T-SQL与CLR Integration混合,为您提供两个世界的好处 .
这很大程度上归结为逻辑的复杂性(或更多程序性) .
If all else fails
如果所有区域都是最佳的(或接近),并且您的设计没有错误 . 我不会't even get into micro-optimisation, I'只是throw hardware at it .
什么硬件?试试reliability and performance monitor找出瓶颈的位置 . 最有可能解决您描述HDD或RAM的问题 .
如果
SqlDataReader
不够快,也许你应该将你的东西存储在其他地方,比如(内存中)缓存 .不,它实际上不仅是最快的方式 - 它是唯一的(!)方式 . 所有其他机制无论如何都在内部使用DataReader .
我怀疑
SqlDataReader
和你要得到的一样好 .SqlDataReader是最快的方法 . 确保使用get by序数方法而不是按列名称获取 . 例如GetString的(1);
同样值得的是在连接字符串中试验MinPoolSize,以便池中始终存在一些连接 .
如何将一列行转换为一行列,并且只读取一行?
SqlDataReader
有一个读取单行的优化(_1438831_的System.Data.CommandBehavior.SingleRow
参数),所以也许它可以提高一点速度 .我看到了几个优点:
单排改进,
无需在每次迭代时访问数组(
reader[0]
),将数组(
reader
)克隆到另一个数组可能比循环遍历元素并将每个数组添加到新数组更快 .另一方面,强制SQL数据库做更多的工作也有一个缺点 .
“提供了一种从SQL Server数据库中读取仅向前行的方法”这是MSDN中SqlDataReader的使用 . SqlDataReder背后的数据结构只允许读取,它被优化用于在一个方向上读取数据 . 在我看来,我想使用SqlDataReader而不是DataSet来进行简单的数据读取 .
你有4套开销 - 磁盘访问 - .net代码(cpu) - SQL服务器代码(cpu) - 在托管代码和非托管代码(cpu)之间切换的时间
首先是
对你来说足够快,如果不是唯一的解决方案是让磁盘更快 . (您可以比SQL Server更快地从SQL Server获取数据)
您可以在C#中定义Sql Server函数然后运行在列上运行;对不起,我不知道怎么做 . 这可能比数据阅读器更快 .
如果您有多个CPU,并且您知道表中间的值,则可以尝试使用多个线程 .
您可以使用您知道安全的分隔符编写一些TSQL,将所有字符串组合成一个字符串 . 然后在C#中再次拆分字符串 . 这将减少托管代码和非托管代码之间的往返次数 .
一些需要考虑的表面级别的事情可能会影响速度(除了数据阅读器):
数据库查询优化
OrderBy很贵
区别很贵
RowCount很贵
GroupBy很贵
等 . 有时你不能没有这些东西,但如果你能用C#代码处理其中的一些东西,它可能会更快 .
数据库表索引(对于初学者,您的WHERE子句中的字段是否已编入索引?)
数据库表数据类型(在给定数据的情况下,您使用的是最小的吗?)
为什么要将datareader转换为数组?
例如,它是否也可以创建一个您不需要转换为数组的适配器/数据表?
您是否查看了实体框架? (可能会慢一点......但如果你没有选择,可能值得研究一下以确保)
只是随机的想法 . 不确定在你的情况下可能会有什么帮助 .
如果响应是加载大量数据的问题,请查看使用异步方法 - BeginReader .
我一直使用它来在后台填充大的GUI元素,同时应用程序继续响应 .
您还没有确切地说明这些数据有多大,或者为什么要将它们全部加载到数组中 .
通常,对于大量数据,您可能希望将其保留在数据库中或让数据库执行繁重的工作 . 但是我们需要知道你正在做什么样的处理,一次需要一个数组 .