如何使用外键从SQLite表中提高DELETE性能?

问题描述 投票:4回答:1

使用外键启用从SQLite中删除表似乎非常慢。有没有什么可以改善性能(不禁用外键)?

import time
import sqlite3

def fk_check(state):
    conn = sqlite3.connect(":memory:")
    c = conn.cursor()
    c.execute("CREATE TABLE parent (id integer primary key, name)")
    c.execute("CREATE TABLE child (id integer primary key, parent_id references parent)")
    c.execute("CREATE INDEX parentindex ON child(parent_id);")

    c.execute(f"pragma foreign_keys={state};")

    for i in range(10000):
        c.execute("insert into parent (name) values (?);", ('name'+str(i),))

    for i in range(5000, 10000):
        c.execute("insert into child (parent_id) values (?);", (i,))

    start = time.time()
    c.execute("delete from parent where id < 5000")
    took = time.time()-start
    print(f'fk-{state}: {took}')

fk_check('on')
fk_check('off')
fk_check('on')
fk_check('off')

有以下输出:

fk-on: 0.8750052452087402
fk-off: 0.0007216930389404297
fk-on: 0.8769822120666504
fk-off: 0.0007178783416748047
python sqlite
1个回答
0
投票

来自the docs

每次应用程序从父表中删除一行时,它都会执行以下SELECT语句的等效操作来搜索子表中的引用行:

SELECT rowid FROM <child-table> WHERE <child-key> = :parent_key_value

如果此SELECT返回任何行,则SQLite断定从父表中删除行将违反外键约束并返回错误。如果修改了父键的内容或者将新行插入到父表中,则可以运行类似的查询。

启用FK后,它会在每次删除时执行额外的工作。我不认为你可以在保留外键约束的同时避免这种情况。

© www.soinside.com 2019 - 2024. All rights reserved.