2009-06-10 4 views
0

フラットテーブルからいくつかの他のテーブルにデータをコピーし、与えられたXMLでマッピングするインポータを作成しました。これは、各製品が複数のプロパティを持つことができ、各プロパティが複数の異なる言語を持つことができる店舗データベース用です。つまり、大量のデータまでかなり高速に集計されます。テーブルからテーブルのインポートへの最適化

今のところ50,000行以上あります。図から分かるように、私は最初の単一の製品を表す各行を繰り返し処理次に、フラットインポートテーブルからデータを読み取り、Iは​​、プロパティマッピングを反復製品ごとに、

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というハッシュテーブルにコピーします。 nullの値はスキップされます。

すべての列がハッシュテーブルにコピーされた後、私はその行を挿入します。

現在のところ、このアプローチでは約700行/分しか処理されないため、このインポートには約1時間かかります。これをどのように最適化できますか?

[EDIT]実際の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

2つのこと:まず、1行あたりの挿入方法を約1000行のキャッシュに変更し、1つのMySQLインサート(multiple insertsを参照)で挿入するように変更しました。

第二に、おそらく最も重要なのは、製品ごとにたくさんの重複があったことですインポートの前にそれらの重複を削除した後、私は同じアクションのために10秒になります...

重複のために彼の選択の結果をチェックしてからインポートしてください。このケースでは、すべての単一の製品を一度選択したいと思っていましたが、各製品をすべての言語バージョンで選択しました。 (つまり、基本的に同じ4つの製品が別の言語であることを意味します)

0

バルク操作はSQLで高速です。 XML文書を一連のSQL問合せに変換できる場合は、パフォーマンスが大幅に向上します。

編集:私はあなたがやろうとしていることを口にしていませんが、あなたはフラットなテーブルで始まり、他のテーブルの束で終わるようです。なぜこれをしないのですか?

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

これはかなり高速ですが、XMLマッピングよりも柔軟性が低くなります。

+0

簡略化したXMLの例を追加しました。 –

+0

"フラット"テーブルの単純な行を追加できますか? "data_1"ラベルには特別な意味がありますか?たとえば、source_idが最初のフィールドなので "data_1"は "source_id"に対応していますか? – Andomar

+0

フラットテーブルには、最初のxmlのすべてのフィールドに1つの行があります。 (この場合は「source_id」列と「data_field」列があります)。 source_idは、マッピングによってフラットテーブルの列を識別するために使用されます。この列が取得され、その "data_field"値がターゲットにコピーされます(マッピングのテーブルと列情報を保持します)。 –

関連する問題