2016-07-15 13 views
0

私は2,760,000行のテーブルを持っています。 mysqlworkbenchでは元のテーブルから*を選択するのに36秒かかります。Mysql/python fetchall()が大きすぎるため結果を処理できません

この既存のテーブルをPythonで使用して別のテーブルを作成したいとします(my_func()を使用して値を変換しています)。

しかし、コマンドラインで実行すると、決して終了しないようです。私は(下記のように)私の最初の選択SQLにLIMIT 0,10を追加した場合

sql = "SELECT ID, Eye, Values FROM my_original_table" 
curQuery.execute(sql) 

for row in curQuery.fetchall():   
    dat = list(row) 
    id = dat.pop(0) 
    eye = dat.pop(0) 
    values = dat.pop(0)  
    v = my_func(values) 
    if v != None : 
     sql = "INSERT INTO new_table VALUES ('%s', '%s', %d);" % (id, eye, v) 
    print(sql) 
    curExe.execute(sql) 

db.commit() 

はしかし、それが正常に動作します。つまり、これは私のプログラムが正しいことを意味します。しかし、これは「限界」なしでは、データはコンピュータが扱うにはあまりにも大きいのですか?これをどうすれば解決できますか? documentationパー

sql = "SELECT ID, Eye, Values FROM ETCEpisodeVisualAcuity LIMIT 0,10" 
+0

ところで、SQLを構築することはありません文字列の書式設定。パラメータ化されたクエリを使用します。 (多くのPython SQLライブラリでは、クエリの%sの前後にある一重引用符を削除し、最後の%をカンマで置き換えることでコード内でこれを修正できます) – geoffspear

+0

270万行は発音しません** * *多く、そうですか? –

+0

ところで、もしあなたが 'new_table'にインデックスを持っていれば、* every * insertの後に再構築されます。これには時間がかかります。答えのために –

答えて

1

db.store_result()はすぐにクライアント に結果セット全体を返します。結果セットが本当に大きい場合、これは の問題である可能性があります。これを回避する方法の1つは、問合せにLIMIT句を追加することです。返す行数を制限するには、 を使用します。もう1つは use_result()を使用して、結果セットをサーバーに保持し、フェッチするときに行単位で を送信します。ただし、サーバー リソースを結びつけ、接続を強化します。すべての行をフェッチするまで、これ以上のクエリを実行することはできません。 私は結果セットが本当に巨大でなければ store_result()を使用することをお勧めします。 はなんらかの理由でLIMITを使用できません。

db = MySQLdb.connect(yourhost,yourname,yourpw,yourdb) 

db.query("SELECT ID, Eye, Values FROM my_original_table") 

r=db.use_result() 

>>> r.fetch_row() 
(('3','2','0'),) 
+0

ありがとう。答えのために – wildcolor

2

使用を(fetchallを呼び出さず)イテレータのようにカーソル:上記

sql = "SELECT ID, Eye, Values FROM my_original_table" 
curQuery.execute(sql) 

for row in curQuery: 
    # ... 

fetchoneでループしながら使用してクエリを処理することと等価である:

curQuery.execute("SELECT ID, Eye, Values FROM my_original_table") 
row = curQuery.fetchone() 
while row is not None: 
    # do something with data... 
    row = curQuery.fetchone() 
+0

ありがとう。あなたのソリューションは私が読むのが簡単です。私が試した後、最終的にいくつかの結果がプリントされます。それから、実際に私の 'my​​_func()'にバグが見つかりました。しかし、私はバグを修正した後、コマンドラインで結果をもう一度表示しません。次に、db.commit()を挿入位置のループに移動しました。その後、印刷物が最終的に動作します。 30秒後に、新しいテーブルに40,000行が作成されているのがわかります – wildcolor

関連する問題