2016-04-08 4 views
1

からデータを読み込み、私はラインプロファイルごとのようにMongoDBにデータをダンプスクレーパー、そして私の他のモジュールにMongoDBからデータを取得しようとしているが、その非常に遅いがありPythonのスピードアップ:MongoDBの遅い

Line #  Hits   Time Per Hit % Time Line Contents 
============================================================== 
    607            @profile 
    608            def get_item_iterator(self): 
    609             """ 
    610             build a generator from the item collection 
    611             """ 
    612   1   1  1.0  0.4   query = {'token': self.token} 
    613             # for item in self.collection.find(query): 
    614             #  yield item 
    615             # return (item for item in self.collection.find(query)) 
    616   1   263 263.0  98.9   items_cur=self.collection.find(query) 
    617   1   2  2.0  0.8   return items_cur 

Total time: 0.168562 s 
File: optim_id.py 
Function: Identify at line 618 

Line #  Hits   Time Per Hit % Time Line Contents 
============================================================== 
    618            @profile 
    619            def Identify(self): 
    620             """ 
    621             identify CTAs 
    622             """ 
    623   1   2  2.0  0.0   try: 
    624   1   1  1.0  0.0    flag=0 
    625   1   280 280.0  0.2    items_cur=self.get_item_iterator() 
    626  112  158137 1411.9  93.8    for item in items_cur: 
    627  111   218  2.0  0.1     if flag==0: 

のでヒットタイムが巨大であることがわかります。どうすればこれを大幅に減らすことができますか? 私はリストの理解がループよりも速いと聞いていますが、私も同様に試みましたが成功しませんでした。

Line #  Hits   Time Per Hit % Time Line Contents 
============================================================== 
    607            @profile 
    608            def get_item_iterator(self): 
    609             """ 
    610             build a generator from the item collection 
    611             """ 
    612   1   2  2.0  0.6   query = {'token': self.token} 
    613             # for item in self.collection.find(query): 
    614             #  yield item 
    615   1   310 310.0  99.4   return (item for item in self.collection.find(query)) 

Total time: 0.150235 s 
File: optim_id.py 
Function: Identify at line 616 

Line #  Hits   Time Per Hit % Time Line Contents 
============================================================== 
    616            @profile 
    617            def Identify(self): 
    618             """ 
    619             identify CTAs 
    620             """ 
    621   1   2  2.0  0.0   try: 
    622   1   328 328.0  0.2    item_list=self.get_item_iterator() 
    623   1  139896 139896.0  93.1    item_record=item_list.next() 

私のMongoDB統計:

db.stats() 
{ 
    "db" : "scrapy_database", 
    "collections" : 102, 
    "objects" : 167007, 
    "avgObjSize" : 1091.1401797529445, 
    "dataSize" : 182228048, 
    "storageSize" : 310439936, 
    "numExtents" : 374, 
    "indexes" : 100, 
    "indexSize" : 6115648, 
    "fileSize" : 469762048, 
    "nsSizeMB" : 16, 
    "extentFreeList" : { 
     "num" : 4, 
     "totalSize" : 6029312 
    }, 
    "dataFileVersion" : { 
     "major" : 4, 
     "minor" : 22 
    }, 
    "ok" : 1 
} 
> collection=db['scraped_rawdata'] 
scrapy_database.scraped_rawdata 
> collection.stats() 
{ 
    "ns" : "scrapy_database.scraped_rawdata", 
    "count" : 100451, 
    "size" : 121793232, 
    "avgObjSize" : 1212, 
    "numExtents" : 13, 
    "storageSize" : 168075264, 
    "lastExtentSize" : 46333952, 
    "paddingFactor" : 1, 
    "paddingFactorNote" : "paddingFactor is unused and unmaintained in 3.0. It remains hard coded to 1.0 for compatibility only.", 
    "userFlags" : 1, 
    "capped" : false, 
    "nindexes" : 1, 
    "totalIndexSize" : 3270400, 
    "indexSizes" : { 
     "_id_" : 3270400 
    }, 
    "ok" : 1 
} 

が、私はあなたのクエリのbath_sizeを高めるようにしてください総

> collection.find({"token":"9a9ec6086bb4a4a7ae8cd44b909b139930e561c3"}).count() 
111 
+1

データベースのサイズはどのくらいですか?あなたのコレクションにインデックスを使用していますか? –

+1

あなたは111項目しか返っていないという理由だけで、そこに行くために多くの作業が行われているわけではありません。特に、「トークン」プロパティには「インデックスがありません」があります。これは結果を取得するための「コレクションスキャン」を意味します。そう、はい、これは100,000以上のエントリを介してあなたが望む111を見つけるために働いています。 「トークン」に索引を追加します。また、「16進」文字列ではなく「バイナリ」表現を格納することも考えられます。その値の「部分文字列」を検索に使用しない限り、バイナリ形式はより少ない領域とメモリを消費します。 –

答えて

1

で111にある項目を照会しています、それはそのすべてのアイテム表示されますデータベースにヒットする必要があります。 tokenフィールドのインデックスも追加します。

+0

あなたが参照している 'cursor.batchSize()'ですか? – aman

+0

はい、それはpythonドライバで設定するための適切な関数に見えます –