2017-03-04 19 views
0

私はsqliteのを使用しています無視し、このようになりますテーブルを持っている:INSERT後にPRIMARY KEYのIDを取得したり、

CREATE TABLE IF NOT EXISTS dirnames (dirnameid INTEGER PRIMARY KEY, 
            dirname TEXT NOT NULL UNIQUE); 
CREATE INDEX IF NOT EXISTS dirnames_idx1 ON dirnames(dirnameid); 
CREATE INDEX IF NOT EXISTS dirnames_idx2 ON dirnames(dirname); 

私は右、任意のディレクトリのdirnameidを取得したいと思います?が私のディレクトリ名に置換されている

INSERT or IGNORE INTO dirnames (dirname) VALUE (?) 
SELECT dirnameid from dirnames where dirname=? 

:今、私はこのようなものをやっています。存在しない -

は、このアクションを行うのsqliteのコマンドが必要になるため、それ以上のこのクエリを最適化する方法はありません。この

答えて

1

を行うには、より効率的な方法があります。

しかし、これを '最適化'する方法があります:LBYLの説明を使用すると、ディレクトリがすでに存在する場合にラウンドトリップを '保存'します。

擬似コード(私はあなたのコードがどのように見えるか見当がつかないので):これは、テーブルに取り組んで唯一のプログラム/スレッドではない場合

悲しいこと
import sqlite3 

#(...) 

connection = sqlite3.connect(':memory:') 
cursor = connection.cursor() 

dirname = 'foo' 
dirnameid = None 

cursor.execute("SELECT dirnameid from dirnames where dirname=?;", (dirname,)) 
dirnameid = cursor.fetchone()[0] 

if not dirnameid: 
    cursor.execute("INSERT or IGNORE INTO dirnames (dirname) VALUES (?);", (dirname,)) 

    # WARNING: The following line should be used if, and ONLY if the access to the sqlite is not concurrent (AKA: Only one connection inserting to the table) 
    dirnameid = cursor.lastrowid 

    # Otherwise, use this: 
    cursor.execute("SELECT dirnameid from dirnames where dirname=?;", (dirname,)) 
    dirnameid = cursor.fetchone()[0] 

connection.close() 

は、このコードは、他の往復が追加されます。

しかし、これは時期尚早の最適化と思われますが、これはすべてのコストをかけて回避する必要があります。 (https://softwareengineering.stackexchange.com/questions/80084/is-premature-optimization-really-the-root-of-all-evil

+0

ありがとうございました。はい、あなたの擬似コードは、項目がテーブルにない場合は3つのステートメントになります。 Hm。はい。ありがとう! – vy32

+0

コードが並行でない場合は3を使用し、それ以外の場合は2を使用します。コードを正確に実行せず、単に質問に答えた –

関連する問題