C# 优化MySQL表到表导入
我编写了一个导入器,它将数据从一个平面表复制到其他几个表中,并用给定的XML映射它们。这是一个商店数据库,其中每个产品可以有几个属性,每个属性可以有几个不同的语言,这意味着它可以很快地汇总成大量的数据 到目前为止,共有50000多行。我当前的导入代码如下所示:C# 优化MySQL表到表导入,c#,mysql,optimization,import,C#,Mysql,Optimization,Import,我编写了一个导入器,它将数据从一个平面表复制到其他几个表中,并用给定的XML映射它们。这是一个商店数据库,其中每个产品可以有几个属性,每个属性可以有几个不同的语言,这意味着它可以很快地汇总成大量的数据 到目前为止,共有50000多行。我当前的导入代码如下所示: string query = "SELECT * FROM " + tableDataProducts + " ORDER BY " + productIdField; DataSet impor
string query = "SELECT * FROM " + tableDataProducts + " ORDER BY "
+ productIdField;
DataSet importData = new DataSet();
Hashtable data = new Hashtable();
db.DoSelectQuery(query, ref importData, tableDataProducts);
foreach (DataRow row in importData.Tables[0].Rows) {
foreach (MapEntry e in mapping[tableObjPropertyValue]) {
string value = row[e.ImportXmlAttributeName].ToString();
if (value.Equals("null",
StringComparison.OrdinalIgnoreCase)
|| value.Length < 1)
continue;
data.Clear();
data.Add("ProductSN", productIdToSn[row[
productIdField].ToString()]);
data.Add("ObjPropertyGroupID", "0");
data.Add("ObjPropertyID", e.ObjPropertyID);
data.Add("LanguageID", e.LanguageID);
data.Add("Value", value);
db.DoPreparedInsertQuery(tableObjPropertyValue, data);
}
}
insert into Product
(id, name)
select source_id, data_field
from FlatTable
该XML被导入到单个表中,每个表中的每个字段都成为一列。有一个映射XML,如下所示:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<DATAPACKET Version="2.0">
<METADATA>
<FIELDS>
<FIELD FieldName="source_id" DisplayLabel="source_id" FieldType="String" FieldClass="TField"/>
<FIELD FieldName="target" DisplayLabel="target" FieldType="Unknown" FieldClass="TField"/>
</FIELDS>
</METADATA>
<ROWDATA>
<ROW source_id="data_1" target="products::id"/>
<ROW source_id="data_2" target="products::name"/>
</ROWDATA>
</DATAPACKET>
target属性包含以下格式的目标表和列:
target='table::column'
批量操作在SQL中速度极快。如果您可以将XML文档转换为一系列SQL查询,则可以显著提高性能
编辑:我不知道你想做什么,但在我看来,你从一张平桌子开始,然后以一堆其他桌子结束。为什么不这样做:
string query = "SELECT * FROM " + tableDataProducts + " ORDER BY "
+ productIdField;
DataSet importData = new DataSet();
Hashtable data = new Hashtable();
db.DoSelectQuery(query, ref importData, tableDataProducts);
foreach (DataRow row in importData.Tables[0].Rows) {
foreach (MapEntry e in mapping[tableObjPropertyValue]) {
string value = row[e.ImportXmlAttributeName].ToString();
if (value.Equals("null",
StringComparison.OrdinalIgnoreCase)
|| value.Length < 1)
continue;
data.Clear();
data.Add("ProductSN", productIdToSn[row[
productIdField].ToString()]);
data.Add("ObjPropertyGroupID", "0");
data.Add("ObjPropertyID", e.ObjPropertyID);
data.Add("LanguageID", e.LanguageID);
data.Add("Value", value);
db.DoPreparedInsertQuery(tableObjPropertyValue, data);
}
}
insert into Product
(id, name)
select source_id, data_field
from FlatTable
这是非常快的,但代价是灵活性不如XML映射。好的,有两件事:首先,我改变了每行插入的方法,缓存大约1000行,并用一个MySQL插入来插入它们(请参阅) 第二,可能也是最重要的一点,就是我每个产品都有大量的复制品,这些复制品累积成一个大的、血腥的烂摊子,需要1个小时才能导入。在导入前消除这些重复项后,我将在10秒钟内完成相同的操作
在导入之前,应检查其选择的结果是否存在重复项。在本例中,我希望只选择一次每个产品,但我选择了每个语言版本的每个产品。(这意味着我有4种基本相同的产品,只是用另一种语言)我添加了一个简化的XML示例。您可以添加一个简化的“平面”表行吗?“data_1”标签是否有特殊含义,例如,“data_1”是否与“source_id”相对应,因为source_id是第一个字段?平面表中第一个xml的每个字段都有一行。(在本例中,它有“源id”和“数据字段”列)。映射使用源id标识平面表中的列。获取此列,并将其“data_field”值复制到目标中(其中包含映射的表和列信息)。唉,这是不可能的,因为存在一些依赖项(例如,ObjPropertyValue需要一个ObjPropertyID,它是在填充表ObjProperty时自动生成的。我的程序确实关联了这些)其他值需要修改(某些ID通过连接其他ID生成)或在导入时检测并插入(基于文件扩展名的MimeType)。