我正在处理一个大型(~10gb)SQLite数据库,其中包含3个表:Documents,其中包含一个id和一个“title”TEXT
列,Terms,其中包含一个id和一个“term”TEXT
列,最后是 DocumentTerms,其中包含一个 id、一个“documentId”INT
和一个“termId”INT
,映射行从术语表到文档表中的行。如果文档多次包含相同术语,则 DocumentTerms 表中会有多个条目。
无论如何,我的问题是我需要对每个术语运行 tfidf 术语权重,其中涉及以下步骤(我包含了我认为需要获取每个步骤的查询):
- 查找该术语在所有文档中出现的次数 -
SELECT COUNT(*) FROM DocumentTerms WHERE termId=id
- 查找总共有多少文档 -
SELECT COUNT(*) FROM Documents
- 查找某个术语出现在多少个文档中 --
SELECT COUNT(*) FROM DocumentTerms WHERE termId=id GROUP BY documentId
显然我只需要运行#2一次。
对于这么大的数据库,每次查询都需要很长的时间。仅找出有多少文档(SELECT COUNT(*) FROM Documents
)大约需要 45 秒。
为了加快速度,我尝试了一些编译指示。我只需要运行一次,所以我并不关心如果我在操作过程中断电或其他什么情况数据库是否会被损坏:
PRAGMA synchronous = OFF
PRAGMA page_size = 4096
PRAGMA cache_size = 16384
PRAGMA temp_store = MEMORY
PRAGMA journal_mode = OFF
PRAGMA locking_mode = EXCLUSIVE
如何加快这些访问时间?
最佳答案
对于只读访问,大多数 PRAGMA
没有任何效果。
只有 cache_size
很重要; page_size
可能会有所帮助,但必须在创建数据库之前设置。
当一个简单的 SELECT COUNT(*)
花费那么长时间时,很明显您没有任何有用的索引。
如果没有数据库结构,很难判断,但以下索引可能会有所帮助:
CREATE INDEX Documents_Id ON Documents(Id)
(您可以使用 Documents
表中的任何小字段来代替 Id
,但通常最好使用主键索引。)
CREATE INDEX DocumentTerms_termId_documentId ON DocumentTerms(termId, documentId)
您可以通过EXPLAIN QUERY PLAN查看查询如何executed .
关于sqlite - 加快 SQLite 查询速度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17902093/