Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用OLEDB将表写入文件非常慢_C#_Performance_Export To Csv_Oledbcommand - Fatal编程技术网

C# 使用OLEDB将表写入文件非常慢

C# 使用OLEDB将表写入文件非常慢,c#,performance,export-to-csv,oledbcommand,C#,Performance,Export To Csv,Oledbcommand,类似的问题已经被提出。但是OP没有按照要求添加代码。所以我会在这里做。代码使用INSERT INTO写入CSV 我尝试了准备好/未准备好的DbCommand?和@占位符以及未准备好的动态SQL。与使用StreamWriter直接写入文件的简单实现相比,所有插入的执行速度要慢100到1000倍 此外,我没有发现用于OleDB的BulkInsert方法。毕竟,微软的SQLServer能够高效地导出到csv,所以他们似乎知道如何做到这一点 请注意,问题只在于写作。阅读真的很快 还要注意的是,我确实有一

类似的问题已经被提出。但是OP没有按照要求添加代码。所以我会在这里做。代码使用INSERT INTO写入CSV

我尝试了准备好/未准备好的DbCommand?和@占位符以及未准备好的动态SQL。与使用StreamWriter直接写入文件的简单实现相比,所有插入的执行速度要慢100到1000倍

此外,我没有发现用于OleDB的BulkInsert方法。毕竟,微软的SQLServer能够高效地导出到csv,所以他们似乎知道如何做到这一点

请注意,问题只在于写作。阅读真的很快

还要注意的是,我确实有一个schema.ini,并且正在运行

我正在使用Net3.5

所以问题是,我的代码有什么问题?或者OleDB中是否存在缺陷?还是有更好的数据提供者来访问cvs

IDbCommand cmd   = connection.CreateCommand(); //conn. type is IDbConnection
var colnames     = new StringBuilder();
var placeholders = new StringBuilder();
DataTable schema = dr.GetSchemaTable();
char sep         = ' ';

foreach (DataRow r in schema.Rows) {
    String name = r["ColumnName"] as String;
    colnames.AppendFormat("{0}{1}", sep, name);
    placeholders.AppendFormat("{0}?", sep);
    sep = ',';
    var p = cmd.CreateParameter();
    //p.DbType = (DbType) r["ProviderType"]; //NUMBER(38) is DateTime? strange!
    p.Size = (int)r["ColumnSize"];
    cmd.Parameters.Add(p);
}

var query2 = new StringBuilder();
query2.AppendFormat ( "INSERT INTO {0} ({1}) VALUES ({2})",
                      tableName, colnames, placeholders );
cmd.CommandText = query2.ToString();
cmd.CommandType = CommandType.Text;
cmd.CommandTimeout = 5;

while (dr.Read()) { // dr is of type IDataReader
    for (int i = 0; i < dr.FieldCount; ++i) {
        String name = dr.GetName(i);
        DbParameter pp = cmd.Parameters[i] as DbParameter; //tried name for i too
        pp.Value = dr.GetValue(i);
    }
    cmd.ExecuteNonQuery();
}
IDbCommand cmd=connection.CreateCommand()//连接类型为IDB连接
var colnames=新的StringBuilder();
var占位符=新的StringBuilder();
DataTableSchema=dr.GetSchemaTable();
char sep='';
foreach(schema.Rows中的数据行r){
字符串名称=r[“ColumnName”]作为字符串;
AppendFormat(“{0}{1}”,sep,name);
占位符.AppendFormat(“{0}?”,sep);
sep=',';
var p=cmd.CreateParameter();
//p、 DbType=(DbType)r[“ProviderType”];//数字(38)是日期时间?奇怪!
p、 Size=(int)r[“ColumnSize”];
cmd.Parameters.Add(p);
}
var query2=新的StringBuilder();
AppendFormat(“插入到{0}({1})值({2})”中,
表名、列名、占位符);
cmd.CommandText=query2.ToString();
cmd.CommandType=CommandType.Text;
cmd.CommandTimeout=5;
而(dr.Read()){//dr属于IDataReader类型
对于(int i=0;i
您是否分析了您的代码以查看时间占用的位置?我敢肯定,当您写入CSV文件时,您将看到一个渐进的减速。批量导出到CSV工作良好的最可能原因是,代码只是直接写入文件,而不是依赖OLEDB抽象层。ExecuteOnQuery方法需要将近一秒钟的时间,我看不到任何渐进的速度减慢。只是太慢了。这是一个Net框架函数,所以我不知道如何分析它。文本驱动程序通常速度慢得令人难以置信。想想文本驱动程序是什么:它试图复制一个以文本文件为后台的关系数据库。如果这是可能的,并且性能良好,人们将抛弃mysql和其他真正的DBMS,只为了一个DB驱动程序的简单性和低成本。实际上,文本数据库驱动程序非常少。您将获得更好的结果,导出到MS Access,然后再从MS Access导出到文本。或者更好——在SQL或ADO中编写INSERT语句所需的时间内,您可以编写到StringBuilder中。@MatthewMartin,我说的是slow的另一个方面。在一个空文件中插入包含几个字节的几列的行不应花费1秒的时间。我认识打字速度更快的人。我的解决方法确实是StringBuilder和StreamWriter,而且工作速度很快。不幸的是,它打破了网络框架的“一个接口,面向所有后端”的理念。我甚至有一个解决办法。但我不喜欢实施变通办法。此外,我不能相信微软没有注意到这个问题。所以我想有人会知道一个神奇的修复方法,也许会更新到Net 4.5?。自2008年以来就知道这个问题——性能损失10^(大),这与我几年前和大约十年前尝试使用文本驱动程序时的2x记忆相匹配。