2

我正在处理一个包含 3 个表的大型(~10gb)SQLite 数据库:Documents,其中包含一个 id 和一个“title”TEXT列,Terms,其中包含一个 id 和一个“term”TEXT列,最后是 DocumentTerms,其中包含一个id、“documentId”INT和“termId” INT,将Terms 表中的行映射到Document 表中的行。如果一个文档多次包含相同的术语,则 DocumentTerms 表中有多个条目。

无论如何,我的问题是我需要对每个术语运行一个 tfidf 术语权重,这涉及这些步骤(我包括了我认为我需要获取每个步骤的查询):

  1. 查找该术语在所有文档中出现的次数——SELECT COUNT(*) FROM DocumentTerms WHERE termId=id
  2. 找出总共有多少个文件——SELECT COUNT(*) FROM Documents
  3. 查找一个术语出现在多少个文档中——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

我怎样才能加快这些访问时间?

4

1 回答 1

1

对于只读访问,这些PRAGMAs 大部分没有任何作用。只有cache_size重要;page_size可能会有所帮助,但必须在创建数据库之前设置。

当一个简单SELECT COUNT(*)的需要这么长时间时,很明显您没有任何有用的索引。没有数据库结构很难判断,但以下索引可能会有所帮助:

CREATE INDEX Documents_Id ON Documents(Id)

(除了Id,您可以使用表的任何字段Documents,但通常最好将主键编入索引。)

CREATE INDEX DocumentTerms_termId_documentId ON DocumentTerms(termId, documentId)

您可以使用EXPLAIN QUERY PLAN检查查询是如何执行的。

于 2013-07-28T08:31:46.953 回答