2013-01-04 103 views
2

我有三个表sqlite3的数据库:SQLite数据库优化

CREATE TABLE document (
    id Int PRIMARY KEY NOT NULL, 
    root_id Int, 
    name Varchar(100), 
    active Tinyint 
); 
CREATE INDEX IDX_documentId ON document (id); 
CREATE INDEX IDX_documentName ON document (name); 

CREATE TABLE dictionary (
    id Int PRIMARY KEY NOT NULL, 
    word Varchar(100) NOT NULL 
); 
CREATE INDEX IDX_dictionaryId ON dictionary (id); 
CREATE UNIQUE INDEX IDX_dictionaryWord ON dictionary (word ASC); 

CREATE TABLE document_index (
    id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, 
    document_id Int NOT NULL, 
    word_id Int NOT NULL, 
    FOREIGN KEY(document_id) REFERENCES document(id), 
    FOREIGN KEY(word_id) REFERENCES dictionary(id) 
); 
CREATE INDEX IDX_documentIndexId ON document_index (id); 
CREATE INDEX IDX_documentIndexDocId ON document_index (document_id); 
CREATE INDEX IDX_documentIndexWordId ON document_index (word_id); 

而且我的SQL脚本,以选择所有文件至极包含从字典单词:

SELECT document.id, document.name 
FROM document 
    INNER JOIN document_index on document_index.document_id=document.id 
    INNER JOIN dictionary on dictionary.id=document_index.word_id 
WHERE dictionary.word LIKE @pQuery 
    AND document.active = 1 
    AND document.root_id in (@pRoot1, @pRoot2, @pRoot3, @pRoot4, @pRoot5, @pRoot6, @pRoot7) 

如果词典包含〜= 400,000条记录,文档〜= 1000条记录和document_index〜= 500,000条记录,查询在我的iPad 2上执行约30秒钟。

如何优化查询或更改数据库的结构(例如添加索引)来减少查询时间?

+0

那么和docuent.root_id上的索引直接跳出来,我怀疑像是你真正的问题,但。什么是作为参数传递(主要) –

回答

0

我找到了解决办法。这个解决方案提高了查询执行速度60!倍。我发现它here和更详细 - here。这很简单,我更换了LIKE表达比较> =和<:

老:

dictionary.word LIKE 'prezident%' 

新:

dictionary.word >= 'prezident' AND dictionary.word < 'prezidentz' /* Added z to the second string*/ 

这个解决方案有一个限制,我可以用一部分寻找字符串,但是在字符串结尾处,即'expr%'。

谢谢大家的帮助!

2

瓶颈很可能是部分WHERE dictionary.word LIKE @pQuery

  1. 你有没有dictionary.word指数,所以SQLite的需要扫描整个表
  2. 您使用LIKE运算符,不能在大多数情况下使用的指标。

您的用例确实需要使用LIKE查询而不是检查字符串是否相等?

+0

我真的需要使用LIKE,因为我需要通过子字符串进行比较。 – alexmac

+0

@Alexander:如果您正在使用LIKE匹配_prefix_,那么仍然_definitely_值得索引。 http://www.sqlite.org/optoverview.html#like_opt –

+0

当您描述您的查询的外观时,我们可能会提出一些建议。但是这需要一个单独的问题。 – Philipp

0

使用dictionary.word LIKE @pQuerydictionary.word = @pQuery代替

运行尝试 “分析”

+0

不幸的是,我不能使用“平等”,因为我需要通过子字符串进行比较。 – alexmac