2016-04-24 5 views
1

データベースに約700万行と2列を追加したいと思います。下記のコードを使用してください:PythonでSQLデータベースに追加するのにかかる時間を短縮する方法

disk_engine = create_engine('sqlite:///screen-user.db') 
chunksize = 1000000 
j = 0 
index_start = 1 

for df in pd.read_csv('C:/Users/xxx/Desktop/jjj.tsv', chunksize=chunksize, header = None, names=['screen','user'],sep='\t', iterator=True, encoding='utf-8'): 
    df.to_sql('data', disk_engine, if_exists='append') 
    count = j*chunksize 
    print(count) 
    print(j) 

実際には長い時間がかかります(数日かかると思います)。これを行うより効率的な方法はありますか? Rでは、data.tableパッケージを使用して大量のデータセットをロードしていますが、1分しかかかりません。 Pythonにも同様のパッケージがありますか?接線のポイントとして、このファイルをデスクトップに物理的に格納したいと考えています。今、私は 'データ'が一時ファイルとして保存されていると仮定しています。どうすればいい?

また、データをデータベースにロードすると仮定すると、1分以内にクエリを実行する必要があります。ここで私は、Python +のSQLを使って何をしたいのかのいくつかの擬似コードは次のとおりです。

#load data(600 million rows * 2 columns) into database 
#def count(screen): 
    #return count of distinct list of users for a given set of screens 

基本的に、私はusers.Isのセットで、このタスクのためには大きすぎるデータを画面数を返すのですか?私はまた、このテーブルを別のテーブルとマージしたい。 Rのfread関数がはるかに高速な理由はありますか?

+1

Gotchaので、SQLiteを使用しています。あなたの質問については、 "PythonがRデータテーブルに相当するのでしょうか?"パンダはその図書館です。あなたのコードの遅い部分は、データベースの書き込みです。異なるユーザを 'df'変数自体から数えることはできませんか?なぜSQLが必要ですか? –

+0

私はデータベースがクエリを実行する方が速いと仮定しました。 Pythonの新しいユーザーとして、dfのレコードはどのように表示されますか?私がprint(df)を実行すると、オブジェクト名が取得され、SQL dbへのデータの書き込みはクエリ作成の面で簡単になり、テーブルの出力も見ることができます。また、pd.read_csvステートメントでデータをロードするのにどれくらいの時間がかかるかわかりません。 – zorny

+0

クエリ自体をSQLに書く方がはるかに簡単ですが、発見したようにデータをデータベースに読み込むのは遅いです。個人的には、[SparkSQL](http://spark.apache.org/docs/latest/sql-programming-guide.html#overview)を参照し、後でデータベースファイルに書き込むことを心配してください。 –

答えて

1

TSVファイルからSQLiteにデータをインポートすることを目標にする場合は、SQLite自体のネイティブインポート機能を試してください。ただ、sqliteコンソールプログラムを開き、このような何か:

sqlite> .separator "\t" 
sqlite> .import C:/Users/xxx/Desktop/jjj.tsv screen-user 

が任意のクエリを実行する前に、適切な索引を作成することを忘れないでくださいを。

+1

MySQLの場合も同じですが、btw。ファイル全体をインポートして、データベースがインポートを処理できるようにします。私は合理的な時間(数十分)で複数のGBファイルでこれをやっています。 – roadrunner66

0

@John Zwinckは既に言っているように、このような量のデータをロードするために、おそらくネイティブのRDBMSのツールを使うべきです。

まず最初にSQLiteは、後でこのデータを結合/マージする必要がある場合、700万行のための適切なツール/ DBではないと思います。

ロード後のデータ処理の種類に応じて、free MySQLを使用するか、クラスタを用意する余裕がある場合(Apache Spark.SQL)、複数のクラスタノードでデータの並列処理を行うことができます。

MySQL DBにデータをロードするには、ネイティブLOAD DATAツールを使用する必要があります。ここ

great article MySQLのためのデータ・ロード・プロセスを最適化する方法を示す図である(異なるため:のMySQLバージョン、MySQLのオプションは、MySQLストレージエンジン:MyISAMテーブルとInnoDBは、等)

結論:使用ネイティブDBのツール特にあなたのデータがメモリに収まらない場合や、ロード後にデータを処理(ジョイン/マージ/フィルタリングなど)したい場合には、パンダの代わりに大量のCSV/TSVデータを効率的にロードすることができます。

+0

MySQLを使用してデータをロードした後、python/pandasを介してそのデータベースとやり取りするのは簡単ですか?また、ラップトップのみを使用している場合はスパークが便利ですか? – zorny

+0

@ zorny、いいえ、考えているのは、処理したいデータがすべてメモリに収まらない場合や、データを簡単に処理(ジョイン、グループ化、集約、フィルタリングなど)できない限り、パンダを使用したくないということです。まれにパンダを使用するチャンク。 – MaxU

+0

@ zorny、1つのマシン/ラップトップでSparkを使用することは、多分それを学ぶためだけには意味がありません...あなたのラップトップですべてのデータを処理しなければならないオプションがない場合は、 MySQLで - リレーショナルデータを処理するために設計された;) – MaxU

関連する問題