sql - 为什么本地 sqlite 数据库上的此查询需要 4 分钟才能执行?

标签 sql performance sqlite database-performance

我正在执行来自 SQLite Expert Personal 的查询在大小约为 6mb 的本地数据库上。我的机器在 Intel i5 CPU (3.1GHz) 上运行带有 4GB 内存的 Windows 7。我希望这会在几秒钟内完成,因为一切都是本地的,但由于某种原因,它在 277667 毫秒(大约 4.5 分钟)内执行。关于为什么相对较小的数据集需要这么长时间的任何想法?如果您需要更多信息,请告诉我

TABLE "userlist" contains about 7k records and 4 columns
TABLE "employeeinfo" contains about 30k records and 8 columns

询问:
CREATE TABLE join1 AS
SELECT a.appname AS APPNAME, a.appid AS APPID,  a.perm AS PERMS, a.holdflag AS HOLDFLAG, b.FirstName AS USERFIRST, b.LastName AS USERLAST, b.DeptName AS USERDEPT,
b.TermDate AS USERTERMDATE, b.logonid AS USERHRLOGON, b.empnum AS USEREMPNUM, b.persontype AS USERPERSONTYPE, b.mgrlogonid AS MGRHRLOGON
FROM userlist AS a
LEFT JOIN
employeeinfo AS b
ON a.appid LIKE b.logonid;

更新:
执行以下操作后,我的执行时间从 4.5 分钟缩短到 110 毫秒:
  • 再次导入我的数据,连接列(a.appid, b.logonid) 都是小写,所以我可以使用 '=' 而不是 LIKE
  • 在 a.appid 和 b.logonid
  • 上创建索引
  • 将 PRAGMA cache_size 从 2000(默认)增加到 100000。我刚刚读到这只持续当前 session 。当我关闭并重新打开数据库时,cache_size 确实回到了 2000
  • 将 PRAGMA page_size 从 1024 增加到 4096(显然,如果您在创建第一个表之前声明,这会有所不同,有人可以确认吗?)
  • 将 PRAGMA journal_mode 从“delete”更改为“wal”。然后我不得不将其更改为“内存”,因为“wal”类型与我正在使用的 Python 版本(2.7.5)不兼容
    6.
  • 最佳答案

    表达式 a.appid LIKE b.logonid无法优化,即使在 appid 上使用不区分大小写的索引也是如此.
    因此,数据库必须检查 userlist 中的每条记录。针对employeeinfo 中的每条记录,所以有 7K × 30K = 210M 比较。

    您应该确保这些表中的字符串具有规范的大写,以便您可以使用普通的 =比较。
    或者,创建一个附加列来存储字符串的小写版本。

    关于sql - 为什么本地 sqlite 数据库上的此查询需要 4 分钟才能执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20555487/

    相关文章:

    mysql - 如何根据其他表的数据在sql中查询更新

    java - Android SQL 数据库组织

    android - 通过修改将 View 转换为位图

    performance - 这个质数相关谓词的瓶颈是什么?

    c# - 如何提高 .Net 中的 JSON 反序列化速度? (JSON.net 还是其他?)

    Android SQLite 更新/插入

    mysql - COUNT 正在计算 LEFT JOIN 上不存在的内容。为什么?

    php - mysql left join or full join with fulltext search results

    java - SQLITE 数据库在 java 中被锁定(IDE NetBeans)

    mysql - 将批量数据 xlsx 导入 mysql?无法转换 xls