SQLite 索引

标签 sql sqlite

我无法决定索引。
就像我有下面的查询需要太多时间来执行:

select count(rn.NODE_ID) as Count,
       rnl.[ISO_COUNTRY_CODE] as Country,
       rnl.[FUNCTIONAL_CLASS] as Functional_Class
from RDF_NODE as rn,
     RDF_LINK as rl,
     RDF_NAV_LINK as rnl 
where rl.[LINK_ID] = rnl.[LINK_ID]
  AND rn.NODE_ID IN (rl.[NONREF_NODE_ID], rl.[REF_NODE_ID])
GROUP BY rnl.[ISO_COUNTRY_CODE],
         rnl.[FUNCTIONAL_CLASS]

当我使用解释查询计划时:

0 0 0 SCAN TABLE RDF_NODE AS rn 使用覆盖 inode (~1000000 行)
0 1 2 SCAN TABLE RDF_NAV_LINK AS rnl(~6645278 行)
0 2 1 搜索表 RDF_LINK AS rl 使用索引 sqlite_autoindex_RDF_LINK_1 (LINK_ID=?) (~1 行)
0 0 0 执行列表子查询 1
0 0 0 使用 TEMP B-TREE 进行分组

所有具有索引的表。

扫描和搜索有什么区别?
我们可以更改订单吗?

最佳答案

SCAN 遍历表中的所有行(按照它们在表中存储的顺序,通常根本没有顺序),而 SEARCH 从表中查找单个行。

SQLite 将所有连接实现为嵌套循环连接。
最外面的表总是通过 SCAN 访问(除非有 WHERE 子句限制要返回的行)。
应使用 SEARCH 访问所有剩余的表以查找匹配记录;另一个 SCAN 表示没有可以用来加快查找速度的索引,因此查找每个匹配项需要搜索整个表。

对于这个特定的查询,一个很大的减速是用于实现 GROUP BY 的临时表。
如果所有分组列都在一个索引中,则不需要这样做:

CREATE INDEX UseABetterIndexNameHere
    ON RDF_NAV_LINK(ISO_COUNTRY_CODE, FUNCTIONAL_CLASS);

(RDF_NAV_LINKRDF_LINK 之间的连接要求 RDF_LINK 行由它们的 LINK_ID 查找,因此该列需要一个索引。
同样,RDF_NODE需要 NODE_ID 上的索引.但这些索引已经存在。)

关于SQLite 索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25619288/

相关文章:

mysql - 将 MySQL 查询转换为 SQL Server 时出错

sql - 在单列上不同,但根据未选择的条件从同一个表返回一行

mysql - 从表中只选择那些恰好有 4 个作者的书?

Android 数据库助手单例和同步

android - 如何在Sqlite数据库中添加所有电话联系人?

php - 检查用户是否投票

sql - 小表中列的非聚集索引

sql - SQL更新表中的列

mysql - 如何与 Git(或 à la Git)同时使用数据库

c# - 如何在 .NET 中将 SQLite 与 NLog 一起使用