为什么本地sqlite DB上的查询需要4分钟才能执行?

时间:2013-12-12 22:21:51

标签: sql performance sqlite database-performance

我正在SQLite Expert Personal上对大小约为6mb的本地数据库执行查询。我的机器在Intel i5 CPU(3.1GHz)上运行Windows 7,内存为4GB。我希望这能在几秒钟内完成,因为一切都是本地的,但由于某种原因,它在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毫秒:

  1. 再次导入我的数据,连接列(a.appid,b.logonid)都是小写的,所以我可以使用'='而不是LIKE
  2. 在a.appid和b.logonid
  3. 上创建了一个索引
  4. 将PRAGMA cache_size从2000(默认)增加到100000.我只读了这个,只持续当前会话。当我关闭并重新打开我的数据库时,cache_size确实回到了2000
  5. 将PRAGMA page_size从1024增加到4096(显然,如果您在创建第一个表之前声明,这有什么不同,有人可以确认吗?)
  6. 将PRAGMA journal_mode从'delete'更改为'wal'。然后我不得不将其更改为'memory',因为'wal'类型与我正在使用的Python版本不兼容(2.7.5) 6。

2 个答案:

答案 0 :(得分:4)

您没有指定通配符,因此请勿在{{1​​}}条件下使用LIKE - 将其更改为ON,并确保=已编入索引。< / p>

答案 1 :(得分:4)

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

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