4

多くの実行は削除で非常に遅いようです(挿入は問題ありません)そして私は誰かがなぜそんなに時間がかかるのか知っているのだろうかと思っていました

以下のコードを検討してください

import sqlite3

db = sqlite3.connect("mydb")
c = db.cursor()
c.execute("DROP TABLE IF EXISTS testing ")
c.execute("CREATE TABLE testing (val INTEGER);")
my_vals2 = [[x] for x in range(1,10000)]

def insertmany(vals):
    c.executemany("INSERT INTO testing (val) VALUES (?)",vals)
    db.commit()

def deletemany1(vals):
    c.executemany("DELETE FROM testing WHERE val=?",vals)
    db.commit()

def deletemany2(vals): #this is fastest even though im looping over to convert to strings and again to join ...
    vals = ["'%s'"%v[0] for v in vals] 
    c.execute("DELETE FROM testing WHERE val IN (%s)"%",".join(vals))
    #DELETE FROM TABLE WHERE x in (1,2,3...)

そして、ipythonからの次の時間結果(timeitは面白いデータを与えていたので:/)

%time insertmany(my_vals2) 
#CPU times: user 0.60 s, sys: 0.00 s, total: 0.60 s Wall time: 0.60 s

%time deletemany1(my_vals2)
#CPU times: user 3.58 s, sys: 0.00 s, total: 3.58 s Wall time: 3.58 s

%time deletemany2(my_vals2)
#CPU times: user 0.02 s, sys: 0.00 s, total: 0.02 s Wall time: 0.02 s

そして、完全を期すために、ここにtimeitの結果を示します(ただし、timeitは2番目のテストで壊れていると思います(またはmsは最初のテストとは異なる単位です))

%timeit insertmany(my_vals2) 
#1 loops, best of 3: 358 ms per loop

%timeit deletemany1(my_vals2)
#1 loops, best of 3: 8.34 ms per loop  <- this is not faster than the above!!!! (timeit lies?)

%timeit deletemany2(my_vals2)
#100 loops, best of 3: 2.3 ms per loop  

では、なぜ多くの実行が削除で遅いのですか?

4

2 に答える 2

2

私はただパントを取っています:それは削除するものを徹底的に検索しなければならないからです。インデックスを付けて試して、報告してください。

CREATE INDEX foo ON testing (val)

http://sqlite.org/lang_createindex.html

于 2012-11-21T00:52:12.040 に答える
2

SQLitesは、テーブルレコードを。でソートされたB+ツリーに格納しますrowid

自動生成されたで挿入する場合rowid、すべてのレコードがテーブルの最後に追加されます。ただし、削除する場合、SQLiteは最初にレコードを検索する必要があります。id列にインデックスが付けられていない場合、これは遅くなります。明示的なインデックスを作成するか(Johnによって提案されたように)、列をINTEGER PRIMARY KEYROWIDにするように宣言します。

インデックスを使用しない場合、つまり一括挿入後にのみインデックスを作成する場合、インデックスを使用した挿入は高速になります。

最後の削除コマンドは、すべてのレコードを一度に削除します。DELETE FROM testingテーブル内のすべてのレコードを削除することがわかっている場合は、レコードをまったく調べる必要がない、だけを使用することで、さらに高速化できます。

于 2012-11-21T08:16:18.400 に答える