データベースに対して SELECT クエリを実行し、〜 33,000 レコードを解析するスクリプトを作成しています。残念ながら、cursor.fetchone()
/cursor.fetchall()
の段階で問題が発生しています。
私は最初にカーソルを一度に次のように繰り返してみました:
# Run through every record, extract the kanji, then query for FK and weight
printStatus("Starting weight calculations")
while True:
# Get the next row in the cursor
row = cursor.fetchone()
if row == None:
break
# TODO: Determine if there's any kanji in row[2]
weight = float((row[3] + row[4]))/2
printStatus("Weight: " + str(weight))
(タイムスタンプと渡された文字列を出力する) の出力に基づいてprintStatus
、スクリプトは各行を処理するのに約 1 秒かかりました。これにより、ループが繰り返されるたびに (LIMIT 1 または何かを使用して) クエリが再実行されていると信じるようになりました。SQLiteStudio [i]and[/ i] 33,000 行すべてを返します。その速度で、33,000 レコードすべてを処理するには約 7 時間かかると計算しました。
それを待つ代わりに、代わりにcursor.fetchall()を使用しようとしました:
results = cursor.fetchall()
# Run through every record, extract the kanji, then query for FK and weight
printStatus("Starting weight calculations")
for row in results:
# TODO: Determine if there's any kanji in row[2]
weight = float((row[3] + row[4]))/2
printStatus("Weight: " + str(weight))
残念ながら、Python 実行可能ファイルは、ラインに到達した時点で 25% の CPU と ~6MB の RAM でロックアップしましたcursor.fetchall()
。スクリプトを約 10 分間実行したままにしましたが、何も起こりませんでした。
~33,000 の返される行 (約 5MB のデータ) は、Python が一度に取得するには多すぎますか? 一度に 1 つずつ繰り返して行き詰まっていますか? または、物事をスピードアップするためにできることはありますか?
編集:ここにいくつかのコンソール出力があります
12:56:26.019: Adding new column 'weight' and related index to r_ele
12:56:26.019: Querying database
12:56:28.079: Starting weight calculations
12:56:28.079: Weight: 1.0
12:56:28.079: Weight: 0.5
12:56:28.080: Weight: 0.5
12:56:28.338: Weight: 1.0
12:56:28.339: Weight: 3.0
12:56:28.843: Weight: 1.5
12:56:28.844: Weight: 1.0
12:56:28.844: Weight: 0.5
12:56:28.844: Weight: 0.5
12:56:28.845: Weight: 0.5
12:56:29.351: Weight: 0.5
12:56:29.855: Weight: 0.5
12:56:29.856: Weight: 1.0
12:56:30.371: Weight: 0.5
12:56:30.885: Weight: 0.5
12:56:31.146: Weight: 0.5
12:56:31.650: Weight: 1.0
12:56:32.432: Weight: 0.5
12:56:32.951: Weight: 0.5
12:56:32.951: Weight: 0.5
12:56:32.952: Weight: 1.0
12:56:33.454: Weight: 0.5
12:56:33.455: Weight: 0.5
12:56:33.455: Weight: 1.0
12:56:33.716: Weight: 0.5
12:56:33.716: Weight: 1.0
SQL クエリは次のとおりです。
//...snip (it wasn't the culprit)...
SQLiteStudio からの EXPLAIN QUERY PLAN の出力:
0 0 0 SCAN TABLE r_ele AS re USING COVERING INDEX r_ele_fk (~500000 rows)
0 0 0 EXECUTE CORRELATED SCALAR SUBQUERY 1
1 0 0 SEARCH TABLE re_pri USING INDEX re_pri_fk (fk=?) (~10 rows)
0 0 0 EXECUTE CORRELATED SCALAR SUBQUERY 2
2 0 0 SEARCH TABLE ke_pri USING INDEX ke_pri_fk (fk=?) (~10 rows)
2 0 0 EXECUTE CORRELATED SCALAR SUBQUERY 3
3 0 0 SEARCH TABLE k_ele USING AUTOMATIC COVERING INDEX (value=?) (~7 rows)
3 0 0 EXECUTE CORRELATED SCALAR SUBQUERY 4
4 0 0 SEARCH TABLE k_ele USING COVERING INDEX idx_k_ele (fk=?) (~10 rows)
0 0 0 EXECUTE CORRELATED SCALAR SUBQUERY 5
5 0 0 SEARCH TABLE k_ele USING COVERING INDEX idx_k_ele (fk=?) (~10 rows)
0 0 0 EXECUTE CORRELATED SCALAR SUBQUERY 6
6 0 0 SEARCH TABLE re_pri USING INDEX re_pri_fk (fk=?) (~10 rows)
0 0 0 EXECUTE CORRELATED SCALAR SUBQUERY 7
7 0 0 SEARCH TABLE ke_pri USING INDEX ke_pri_fk (fk=?) (~10 rows)
7 0 0 EXECUTE CORRELATED SCALAR SUBQUERY 8
8 0 0 SEARCH TABLE k_ele USING AUTOMATIC COVERING INDEX (value=?) (~7 rows)
8 0 0 EXECUTE CORRELATED SCALAR SUBQUERY 9
9 0 0 SEARCH TABLE k_ele USING COVERING INDEX idx_k_ele (fk=?) (~10 rows)