优化MySQL表到表导入

时间:2009-06-10 07:25:09

标签: c# mysql optimization import

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

目前有超过50,000行。我当前的导入代码如下所示:

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);
            }
        }

可以看出,我首先从平面导入表中读取数据,然后迭代表示单个产品的每一行,并针对每个产品迭代属性映射并将每个属性复制到名为{{1}的Hashtable中}。 null 值被跳过。

将所有列复制到哈希表后,我插入行。

目前,这种方法每分钟只处理大约700行,这导致导入大约需要一个小时。我该如何优化呢?

[编辑]

以下是XML的简化版本,因为实际的XML太大而无法在此处显示:

data

将此XML导入到单个表中,每个FIELD都成为一个列。有一个映射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="data_field" DisplayLabel="data_field" FieldType="Unknown" FieldClass="TField"/>
</FIELDS>
</METADATA>
<ROWDATA>
   <ROW source_id="data_1" data_field="some string"/>
   <ROW source_id="data_2" data_field="another string"/>
</ROWDATA>
</DATAPACKET>

target属性包含以下格式的目标表和列:<?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>

2 个答案:

答案 0 :(得分:0)

SQL中的批量操作很快。如果您可以将XML文档转换为一系列SQL查询,那么可以显着提高性能。

编辑:我不知道你想要做什么,但在我看来,你从一张平面桌开始,并以一堆其他桌子结束。为什么不这样做:

insert into Product
(id, name)
select source_id, data_field
from FlatTable

这是相当快的,但代价是灵活性低于XML映射。

答案 1 :(得分:0)

好的,有两件事:首先,我已经将每行插入方法更改为缓存大约1000行并使用单个MySQL插入插入它们(请参阅multiple inserts)。

其次,也许最重要的是,每个产品都有很多重复产品,这些产品累积成一个大的,血腥的混乱,需要1小时才能导入。在导入之前消除了这些重复项后,对于相同的操作,我只需要10秒......

在导入之前,应该检查他选择重复项的结果。在这种情况下,我想选择每一个产品一次,但我选择了每个产品的每种语言版本。 (意思是我有4种基本相同的产品,只是用另一种语言)