2017-06-20 13 views
0

私は、ローカルSQLiteデータベースにデータのサブセットを抽出するOracleデータベースを用意しています。私のコードは基本的に以下の通りです:OracleからSQLiteへのINSERTの最適化(Python3)

print(datetime.datetime.now()) 

#Oracle portion of the script 
sql = '''select [columns] from [table] where [condition]''' 
oracle_cursor.execute(sql) 

print(datetime.datetime.now()) 

#SQLite portion of the script 
sqlite_conn.executeany('''INSERT into [table] 
          ([columns]) 
          values (?,?,?...etc.)''', 
          oracle_cursor.fetchall() 
         ) 
sqlite_conn.commit() 
sqlite_conn.close() 

それは必要なことですが、私が望む以上に時間がかかります。 Oracleの部分の実行は、実際には約3分で驚くほど高速です。しかし挿入にはかなりの時間がかかります。私はバッファ設定などのようなSQLiteの設定で遊んだことはありません。何も50行/秒を壊すことはありません。最初の3分間はネットワークアクティビティが急増していますが、上から2番目の日時を表示すると、ネットワークアクティビティはありません。これにより、ボトルネックは私がコード化したものだとわかります。私のコードは挿入時に効率が悪いですか?もしそうなら、私が後にしているものを得る良い方法はありますか?

答えて

2

fetchall()は、すべてのデータをメモリにロードします。 executemanyはどのイテレータでも動作できるので、これは必要ではありません。 oracle_cursor.fetchall()oracle_cursorに置き換えてください。

また、1つのトランザクションを使用していることを確認してください。 (自動コミットモードを有効にしている場合は、明示的にトランザクションを開始する必要があります)。

+0

この問題を抱えている他の人には:これは書き込み時間/行を少しスピードアップしました。私はネットワークトラフィックを見てみると、データベースとマシンの間に問題があることが判明しました。私はただデータが転送されていないと仮定しました。タスクマネージャのネットワーキングタブのグラフに表示されなかったデータが非常に少量*転送されていることが判明しました。 insertコマンドをカーソルの各行を出力するforループに置き換えることで、これを発見しました。これは、挿入物ごとに印刷物あたり*正確に*を要したので、おそらくこのシナリオには最適です。 – mkingsbu