2013-01-04 101 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