C# 优化MySQL表到表导入

C# 优化MySQL表到表导入,c#,mysql,optimization,import,C#,Mysql,Optimization,Import,我编写了一个导入器,它将数据从一个平面表复制到其他几个表中,并用给定的XML映射它们。这是一个商店数据库,其中每个产品可以有几个属性,每个属性可以有几个不同的语言,这意味着它可以很快地汇总成大量的数据 到目前为止,共有50000多行。我当前的导入代码如下所示: string query = "SELECT * FROM " + tableDataProducts + " ORDER BY " + productIdField; DataSet impor

我编写了一个导入器,它将数据从一个平面表复制到其他几个表中,并用给定的XML映射它们。这是一个商店数据库,其中每个产品可以有几个属性,每个属性可以有几个不同的语言,这意味着它可以很快地汇总成大量的数据

到目前为止,共有50000多行。我当前的导入代码如下所示:

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)。