2012-04-11 16 views
1

大きなXMLを解析する必要があります。 f.ex 100mb(さらに多くの場合があります)。例についてはPHPでBIG XMLを解析する

<notes> 
    <note> 
    <id>cdsds32da435-wufdhah</id> 
    <to>Tove</to> 
    <from>Jani</from> 
    <heading>Reminder</heading> 
    <body>Don't forget me this weekend!</body> 
    </note> 


x 1000000 different notes(or even more) 

</notes> 

各ノートには、国連のユニークなIDを持っています XMLは次のようになります。私がXMLを構文解析するときには、INSERT以外に特定のIDによるメモがDBに存在するかどうかを最初に調べる必要があります。

問題はパフォーマンスです(2時間かかります)。私はDBからすべてのIDを取ることを試みる(しかしまた大きい)1つのSELECTので、私はDBを毎回尋ねると私はPHPの配列(メモリ)にそれらを持っていない。私は「VEの

$sql = "SELECT id FROM 'notes'"; 
... 
$ids = Array with all ids 

もループでxml_parserでXMLをパースさ:

while($data = fread($Xml, '512')) { 
    xml_parse($xmlParser, $data); 
} 

は、私はPHPがそれを処理するためにあまりにも大きな変数を生成することがありsimple_xml_parserでXMLをパースと思います。

if (array_search($note->id, $ids) === FALSE) { 
    //than insert it 
} 

しかし、それは時間がかかりすぎる:

そして、私はそれが$ idを中に存在する場合、私はチェックのノートIDを持っているときよりも

。だから、PHPにはJudy Arraysという特別な配列が付属していることが判明しました http://php.net/manual/en/book.judy.phpこれが正しいのかどうかはわかりません - 私はBIG配列を素早く解析することを意味します。

私はMemcachedでもDBからのIDを多くの変数に格納すると思いますが、適切な解決策を探したいと思います。

DBテーブルには、処理速度を上げるためのインデックスもあります。 XMLは毎週成長します:)そして、最後のXMLからのすべてのノートに新しいノートを加えたときに毎回conatinsされます。

質問: PHPでBIG ARRAYSを高速で解析するには?これはジュディーアレイですか?そして、DBからすべてのIDを変数に格納するのは良い解決策ですか? PHPで一度に大きくなることがあります。

+0

メモリが十分にある限り、SimpleXMLはこれで問題ありません。データベースクエリーがXML内の重複IDを検出するだけの場合、SimpleXMLを使用すると、データベースにまったくアクセスする必要がないことを意味します。 PHPのために十分なRAMを設定するだけです。 ') – halfer

+0

巨大なXML文書をいくつかの簡単なファイル操作でいくつかの管理可能なものに分割することもできます。あなたのXMLファイルが絶えず成長しているなら、あなたはそれについて何かしなければなりません。たぶん1か月に1つのXMLファイルがありますか? – halfer

+1

いいえ、xml_parse()はあなたが必要とするもので、バッファを読み込むだけで、それ以降はそれをきれいにすることができます。参照のための連想配列を作成しているように見えますが、 'if(isset($ ids-> id)))'のような高速チェックのために 'isset()'という言語構造を使用します。これが本当に速くなるのに本当に役立つかどうかはわかりません。多分あなたは[SplFixedArray](http://php.net/splfixedarray)を見てみるべきです。 –

答えて

1

私が解析したとき、私はJavaソリューション(SAXパーサー)を使用していました。まず、XML(RDF形式)からMySQLデータベースに非常に大量のデータを転送する必要がありました。私のPHPソリューションはこのタスクを6時間以上実行しました。しかし、Javaソリューションは15分後に同様のタスクを実行しました。だから私はあなたに話すことができます:SAXパーサーに基づいてJavaソリューションを使用しようとします。

+0

PHPには[SAXのようなXMLパーサ] (http://php.net/manual/book.xml.php)、[libxmlベースのXMLリーダー](http://php.net/manual/book.xmlreader.php)もあります。ちょうどFYI。 – hakre

1

アイテムを挿入する前にそのアイテムがDBに存在するかどうかを確認する必要がありますか? DBに「存在しなければ挿入する」と言うことができます:IDにユニークなキーを置き、INSERT IGNOREを使用します。

+0

はい、私はそれが新しいノートを挿入し、ノートが新しいときに別のテーブルに別のテーブルを作成するので、必要です。 – Radek