Как я могу улучшить производительность DELETE из таблицы SQLite с внешними ключами? - PullRequest
0 голосов
/ 14 февраля 2019

Удаление из таблицы в 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

1 Ответ

0 голосов
/ 14 февраля 2019

Из документов :

каждый раз, когда приложение удаляет строку из родительской таблицы, оно выполняет эквивалент следующего оператора SELECT для поиска ссылок на строки вдочерняя таблица:

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

Если этот SELECT вообще возвращает какие-либо строки, SQLite приходит к выводу, что удаление строки из родительской таблицы нарушит ограничение внешнего ключа и возвращает ошибку.Подобные запросы могут выполняться, если содержимое родительского ключа изменено или новая строка вставлена ​​в родительскую таблицу.

При включенных FK он выполняет дополнительную работу при каждом удалении.Я не думаю, что вы можете избежать этого, сохраняя ограничение внешнего ключа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...