3

SQLite を使用するには connect() と cursor() を使用します

self.connector = sqlite3.connect(self.dbFile)
self.cursor = self.connector.cursor()

使用をやめるには close() を使用します。

self.cursor.close()

それらは(処理時間の観点から)どれくらい高価ですか?絶対に必要なものだけを使う必要があるほど高価ですか?それとも、関数内で複数回使用しても問題ありませんか?

追加した

次の簡単なコードでテストしました。proc1() は、クエリを実行するときに常に開いたり閉じたりするコードを使用し、proc2() は 1 回だけ実行します。

from sqlite import *
import timeit
import math

def proc1():
    db = SQLiteDB("./example.db", False)
    db.getOpenRunClose("SELECT * from Benchmark")
    db.getOpenRunClose("SELECT * from Benchmark")
    db.getOpenRunClose("SELECT * from Benchmark")
    db.getOpenRunClose("SELECT * from Benchmark")
    db.getOpenRunClose("SELECT * from Benchmark")
    db.getOpenRunClose("SELECT * from Benchmark")

def proc2():
    db = SQLiteDB("./example.db")
    res = db.runSQLToGetResult("SELECT * from Benchmark")
    res = db.runSQLToGetResult("SELECT * from Benchmark")
    res = db.runSQLToGetResult("SELECT * from Benchmark")
    res = db.runSQLToGetResult("SELECT * from Benchmark")
    res = db.runSQLToGetResult("SELECT * from Benchmark")
    res = db.runSQLToGetResult("SELECT * from Benchmark")
    db.close()

if __name__ == '__main__':
    t = timeit.Timer(proc1)
    count = 5000
    print t.timeit(count) / count

    t = timeit.Timer(proc2)
    count = 5000
    print t.timeit(count) / count

結果は次のとおりです。

0.00157478599548
0.000539195966721
4

3 に答える 3

5

接続はかなりコストがかかります (ファイルを開くことに相当します) が、カーソルは必要な数だけ使用するわけではありません[1]。自動コミットモードであっても、トランザクションの開始と、特に挿入または更新がある場合 (またはもちろんテーブルまたはインデックスを作成する場合) のコミットにコストがかかりますこれは、データベース エンジンがコミットを完了する前にデータをディスクに同期する必要があり (耐久性を保証するために必要)、最新のハードウェアでは単純にコストがかかるためです。(トランザクションは、影響を与える可能性のある DB ファイルのロックを行う必要があるため、コストを開始します。)

ステートメントのコンパイルにも少しコストがかかります。可能であれば、コンパイルされたステートメントを再利用します。もちろん、とにかくそれを行う必要があります。なんで?これは、生成された SQL にユーザー データを入れてはならないためです。これは、SQL インジェクションの脆弱性の問題につながるだけでなく、実行するたびに DB エンジンにステートメントの再コンパイルを強制します。コンパイルされたステートメントはより安全で (おそらく) 高速です。


[1]もちろん、必要以上のカーソルを使うのはばかげています。それはただの時間と労力の無駄です。

于 2010-09-19T20:10:25.863 に答える
1

接続は、比較的コストのかかる操作です。sqlite connect は、ほとんどの DB と比較して信じられないほど高速で軽量ですが。実際には、「fopen」と sqlite マスター テーブルからのいくつかの読み取りです。

ほとんどのクエリは、カーソルを要求するかどうかに関係なく内部的に使用します。カーソルは大きな行セットを参照するための単なるハンドルであるため、明示的なカーソルのコストはほとんどかかりません。大きな結果セットを処理する場合、カーソルは実際にはより効率的です。最初の結果行が利用可能になるとすぐにアクセスできます。一度にメモリ内に保持できる行数は限られています。答えはあなたが望んでいたものではないと判断してください。

また、「準備された」ステートメントの推奨事項を支持します。セキュリティが向上し、クエリをインテリジェントにキャッシュすると、sqlite が同じ sql を常に解析する必要がなくなります。

于 2010-09-21T03:09:51.563 に答える
1

接続は、ファイルを開くだけではありません。データベースに対してクエリを実行するとすぐに、sqlite_master テーブル内のすべての SQL を解析する必要があります。したがって、接続にかかる時間は、データベースの複雑さに大きく依存します。単純なデータベースは数ミリ秒で接続できますが、大規模なデータベースはさらに時間がかかります。私たちのクロックは約 45 ミリ秒です (100 以上のテーブル、数百のトリガー)。

于 2010-09-21T03:30:15.023 に答える