2012-12-27 23 views
7

tôi tạo ra một bảng sử dụng sơ đồ như vậy:Làm thế nào để cải thiện hiệu suất sqlite như tuyên bố

CREATE TABLE wordIndex(id integer primary key, word varchar(128), offset integer, length integer); 
CREATE INDEX word_idx on wordIndex(word); 

Bây giờ bàn có khoảng 450.000 hàng records.When tôi sử dụng Giống như tuyên bố Dưới đây trên ipod4, hiệu suất là không tốt: chọn * từ wordIndex nơi từ như 'test acces%'; Sử dụng kết quả giải nghĩa:

explain select * from wordIndex where word like 'test acces%'; 
0|Trace|0|0|0||00| 
1|Goto|0|16|0||00| 
2|OpenRead|0|2|0|4|00| 
3|Rewind|0|14|0||00| 
4|String8|0|2|0|test acces%|00| 
5|Column|0|1|3||00| 
6|Function|1|2|1|like(2)|02| 
7|IfNot|1|13|1||00| 
8|Rowid|0|4|0||00| 
9|Column|0|1|5||00| 
10|Column|0|2|6||00| 
11|Column|0|3|7||00| 
12|ResultRow|4|4|0||00| 
13|Next|0|4|0||01| 
14|Close|0|0|0||00| 
15|Halt|0|0|0||00| 
16|Transaction|0|0|0||00| 
17|VerifyCookie|0|2|0||00| 
18|TableLock|0|2|0|wordIndex|00| 
19|Goto|0|2|0||00| 

Tôi có thể cần tạo thêm chỉ mục đảo ngược để cải thiện hiệu suất hoặc ...? Cảm ơn bạn trước!

+1

Bạn đang sử dụng chỉ có mô hình này cho NHƯ (ví dụ: bắt đầu với)? –

+0

Có, chỉ cần "aaa%" mô hình – ericfang

Trả lời

10

Chỉ mục và like không đồng hành với hầu hết các cơ sở dữ liệu. Việc đặt cược tốt nhất là phải viết lại các truy vấn như một truy vấn nhiều, nếu có thể, bởi vì chỉ số sau đó sẽ được sử dụng: (. Các cú đúp mở là ký tự ASCII ngay sau khi 'z')

select * 
from wordIndex 
where word between 'test acces' and 'test acces{' 

Nếu bạn đang tìm kiếm các mẫu ở đầu từ (nói '% test'), thì bạn có thể phải từ bỏ bản thân để quét toàn bộ bảng.

EDIT:

Indexes và like * do` hòa hiện nay ở hầu hết các cơ sở dữ liệu khi các mô hình bắt đầu với một hằng số, vì vậy bạn có thể làm:

select * 
from wordIndex 
where word like 'test acces%' ; 

Tôi không chắc chắn 100% về Mặc dù vậy, SQLite, hãy kiểm tra kế hoạch thực thi để xem nó có sử dụng chỉ mục hay không.

+0

Cảm ơn Gordon Lionff, nó làm công việc dễ đọc. Trước khi truy vấn viết lại: Thời gian thực hiện: 1.756531 giây, sau khi truy vấn viết lại: Thời gian thực hiện: 0.011285 trên iPod Touch 4 của tôi. – ericfang

+0

Tnx nhưng phân biệt chữ hoa chữ thường! – alizx

5

Hãy thử điều này:

SELECT * FROM wordIndex 
WHERE word COLLATE NOCASE BETWEEN @SearchString AND @SearchString || '~~~~~~~~~~' 

"~" là biểu tượng ASCII lớn nhất.

2

Tôi sẽ có một câu trả lời hơi khác so với Gordon Linoff, nhưng với cách tiếp cận tương tự.

Nếu bạn muốn giữ lại bất kỳ ký tự mà làm theo 'acces test' bạn nên thử điều này:

SELECT * FROM wordIndex 
WHERE word > 'test acces' AND word < 'test accet'; 
Các vấn đề liên quan