2009-06-10 58 views
0

我已经编写了一个导入程序,它将数据从平坦表复制到其他几个表中,并通过给定的XML映射它们。这是一个商店数据库,每个产品可以有多个属性,每个属性可以有多种不同的语言,这意味着它可以快速地总结大量的数据。优化MySQL表到表导入

现在有超过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); 
      } 
     } 

如可以看到的,我首先读取从扁平进口表中的数据,然后遍历代表单个产品的每一行和每一产品我遍历属性映射并将每个属性复制到名为data的Hashtable中。 null值被跳过。

毕竟列复制到哈希表,我插入的行。

目前,该方法仅约为每分钟700行,这将导致该进口以约一小时处理。我怎样才能优化这个?

[编辑]

这里是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="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> 

此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='table::column'

回答

0

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

其次,也可能是最重要的,是,我是有很多每个产品重复,其积累成一个大的,血腥的混乱在1小时导入的。在导入之前消除这些重复后,我只剩下10秒同样的动作...导入之前

每个人都应该检查他的选择的结果进行重复。在这种情况下,我想选择每一个产品一次,但我选择每种语言版本的每个产品。 (意思是我有4个产品,基本上是相同的,只是在另一种语言)

0

批量操作在SQL中闪电般快速。如果您可以将您的XML文档翻译成一系列SQL查询,那可以显着提高性能。

编辑:我不神交你想要做什么,但在我看来,你开始与一个平坦的桌面,并与一群其他表的结束。为什么不这样做:

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

这是非常快速的,代价是不如XML映射灵活。

+0

我添加了一个简单的XML实例。 – 2009-06-10 09:20:45

+0

你可以添加一个简单的“平”表的行吗?对于“data_1”标签是否有特殊含义,例如“data_1”是否对应于“source_id”,因为source_id是第一个字段? – Andomar 2009-06-10 10:16:52

+0

平坦表有第一个xml的每个字段的一行。 (在这种情况下,它具有“source_id”和“data_field”列)。源映射使用source_id来标识扁平表中的列。该列被采用并且其“data_field”值被复制到目标(其保存映射的表和列信息)。 – 2009-06-10 10:26:06