使用子查询加速大量插入外键

时间:2013-07-08 08:27:35

标签: python sql sqlite

我必须插入海量数据(从Python程序到SQLite数据库),其中许多字段通过外键验证。

查询如下所示,我使用executemany()

执行插入
INSERT INTO connections_to_jjos(
    connection_id,
    jjo_error_id,
    receiver_task_id
    sender_task_id
)
VALUES
(
    :connection_id,
    (select id from rtt_errors where name = :rtx_error),
    (select id from tasks where name = :receiver_task),
    (select id from tasks where name = :sender_task)
)

大约300次插入需要15秒,我认为这样做太多了。在生产中,应该有大量1500个插入块。在没有外键子查询的类似情况下,速度令人难以置信。很明显,FK会增加开销并减慢过程,但这太过分了。

我可以进行预查询以捕获所有外键ID,然后直接插入它们,但我觉得必须有更清晰的选项。

另一方面,我已经阅读了Isolation level,如果我不理解它,可能是在每个SELECT查询之前,有一个自动COMMIT来强制完整性......也可能导致这个过程变慢,但我尝试以这种方式工作是完全不成功的。

也许我对FK做了一些本质上的错误。如何提高性能?

其他信息

查询:

EXPLAIN QUERY PLAN select id from rtt_errors where name = '--Unknown--'

输出:

SEARCH TABLE
    rtt_errors

USING COVERING INDEX sqlite_autoindex_rtt_errors_1 (name=?) (~1 rows)

我在rtt_errors.name中创建了一个索引,但显然它没有使用它。

1 个答案:

答案 0 :(得分:1)

从理论上讲,Python的默认COMMIT不应该在连续的INSERT之间发生,但是你的极差性能看起来好像正是这样。

isolation level设置为None,然后围绕所有{{1}执行一对BEGIN / COMMIT个命令一次 }第