我有一个简单的 SQL 表结构,其中包含三个表:entry(~70k 行)、tag(~27k 行)和entry_tag(~250 万行)。entry_tag -table包含条目和标签之间的关系(nn 关系),就像这个entry_tag(entry_id,tag_id,...)。
当我第一次尝试使用特定标签获取所有entry_id时,我进行了如下查询
SELECT entry_id FROM entry_tag et, tag t
WHERE t.id=et.tag_id AND t.name LIKE 'Something';
没有明显的原因,在 Win7 x64(i5-2500K,8GB RAM,7200rpm 硬盘)上的 Adobe Air 应用程序上的查询花费了 6 秒以上,这太慢了(特别是对于更复杂的INTERSECT
查询)。在 SQLite 命令行工具查询立即返回结果。我比较了 cliEXPLAIN
和EXPLAIN QUERY PLAN
Air(使用基于 Air 的 SQLite Sorcerer)和相同的结果。两个查询都使用索引。
在我通过切换表的顺序来重组查询之后,性能在 Air 中成倍增长到 250 毫秒,这是令人满意的:
SELECT entry_id FROM tag t, entry_tag et
WHERE et.tag_id=t.id AND t.name LIKE 'Something';
所以我想知道,为什么 cli 工具比 Adobe Air 环境快得多?对于背景信息,我已经使用 PHP(所有列INTEGER
或TEXT
)生成了 db 文件。
以下是原始慢查询的查询计划:
sele order from deta
---- ------------- ---- ----
0 0 0 SCAN TABLE entry_tag AS et USING INDEX idx_et_eid (~1000000 rows)
0 1 1 SEARCH TABLE tag AS t USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)
(~1000000 行看起来很糟糕;)