python - 在插入或忽略后获取主键的 ID

标签 python sqlite optimization query-optimization

我正在使用 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=?

其中 ? 替换为我的目录名称。

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

最佳答案

无法进一步优化此查询,因为它需要在 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)

关于python - 在插入或忽略后获取主键的 ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42602078/

相关文章:

c++ - 8 个后续字节的测试未转换为单个比较指令

python - 有没有一种方法可以让我从 CSV 文件中绘制数据,其中列中的每 10 个数据点都是同一图表中的不同线?

python - 查找列表中两个标签之间的元素

python - 有没有办法在 Django 中重新加载后保留 html 复选框状态?

android - 有人可以详细说明和解释这种代码。我想了解更多关于它的信息来建立数据库

ios - XMPPMessageArchivingCoreDataStorage 重复条目 - XMPP MUC

python - 网状结构的配置/安装问题 [R]

android - 可以从 Android SQLiteConstraintException 获取特定的错误详细信息吗?

java - 如何通过 Java 使用 Fico Xpress (Mosel)?

git - 从 PS1 提示符运行 git update-index --refresh 安全吗?