【问题标题】:get the ID of a PRIMARY KEY after an INSERT OR IGNORE在 INSERT OR IGNORE 之后获取 PRIMARY KEY 的 ID
【发布时间】:2017-07-24 22:23:26
【问题描述】:

我正在使用 sqlite 并且有一个如下所示的表:

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=?

? 替换为我的目录名称。

有没有更有效的方法来做到这一点

【问题讨论】:

    标签: python sqlite optimization query-optimization


    【解决方案1】:

    没有办法进一步优化此查询,因为它需要在 sqlite 上执行此操作的命令 - 不存在。

    但是,有一种“优化”它的方法:您可以尝试使用 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)

    【讨论】:

    • 谢谢。是的,在项目不在表中的情况下,您的伪代码会产生 3 条语句。嗯。好的。谢谢!
    • 如果代码不是并发的,可能会使用3,否则只会使用2。没有完全运行代码,只是为了回答问题
    猜你喜欢
    • 2010-10-07
    • 2015-07-30
    • 1970-01-01
    • 2023-02-06
    • 1970-01-01
    • 2013-03-22
    • 1970-01-01
    • 2011-03-16
    • 1970-01-01
    相关资源
    最近更新 更多