2012-10-21 25 views
5

Tôi đã cố gắng để có được sqlite để sử dụng một chỉ mục với một không có avail. Ive đã thử nocase collate và vẫn không có may mắn. Bất cứ ai cũng có bất kỳ ý tưởng về làm thế nào để có được sqlite để làm một giống như đánh một chỉ mục. Cảm ơn trướcsqlite không sử dụng chỉ mục giống như truy vấn

DROP TABLE IF EXISTS "test"; 
DROP TABLE IF EXISTS "test2"; 
DROP TABLE IF EXISTS "test3"; 
create table test(name TEXT COLLATE NOCASE); 
create table test2(name TEXT); 
create table test3(name TEXT); 
create index idx_test_name on test(name); 
create index idx_test2_name on test2(name); 
create index idx_test3_name on test3(name COLLATE NOCASE); 
insert into test(name) values('dan'); 
insert into test2(name) values('dan'); 
insert into test3(name) values('dan'); 
--explain query plan select * from test where name like 'test%' 
-- explain query plan select * from test2 where name like 'test%' 
-- explain query plan select * from test3 where name like 'test%' 
+0

Có chỉ mục không đảm bảo chỉ mục sẽ không được sử dụng. –

Trả lời

1

Trong SQLite 3.6.23.1, chỉ số trên test được sử dụng:

> explain query plan select * from test where name like 'test%'; 
TABLE test WITH INDEX idx_test_name 

> explain query plan select * from test2 where name like 'test%'; 
TABLE test2 

> explain query plan select * from test3 where name like 'test%'; 
TABLE test3 

Với một phiên bản phát triển của SQLite 3.7.15, cả test 's và test3' chỉ số s được sử dụng (chỉ số trên test2 được sử dụng cho quét, không tìm kiếm):

> explain query plan select * from test where name like 'test%'; 
SEARCH TABLE test USING COVERING INDEX idx_test_name (name>? AND name<?) (~31250 rows) 

> explain query plan select * from test2 where name like 'test%'; 
SCAN TABLE test2 USING COVERING INDEX idx_test2_name (~500000 rows) 

> explain query plan select * from test3 where name like 'test%'; 
SEARCH TABLE test3 USING COVERING INDEX idx_test3_name (name>? AND name<?) (~31250 rows) 

vì vậy, câu trả lời là để cập nhật SQLite.

+0

Cảm ơn vì điều đó, tôi đã sử dụng phần mở rộng firefox để kiểm tra phiên bản cũ hơn. Sử dụng phiên bản mới hơn hoạt động – aboutme

11

Trích từ danh sách email sqlite (http://www.mail-archive.com/[email protected]/msg27760.html)

LIKE là đựng pin- không nhạy cảm theo mặc định. Để sử dụng chỉ mục của bạn, bạn cần phải làm cho chỉ số không phân biệt chữ hoa chữ thường:

TẠO INDEX test_name ON test (tên COLLATE NOCASE);

hoặc làm cho trường hợp nhạy cảm với chữ hoa chữ thường:

PRAGMA case_sensitive_like = 1;

+0

Cũng trên tài liệu http://www.sqlite.org/optoverview.html – Himanshu

+0

Xin chào, cảm ơn mọi người trả lời, tuy nhiên sau khi kiểm tra nocase đối chiếu trên chỉ mục, chỉ mục vẫn không được sử dụng.Ive đã cập nhật mã ví dụ của tôi với test3 để kiểm tra kịch bản nếu có ai đó muốn thử. Bất kỳ ý tưởng nào khác? – aboutme

0

Từ docs:

khoản đó được cấu tạo của các nhà điều hành NHƯ hoặc GLOB đôi khi có thể được sử dụng để hạn chế chỉ số. Có nhiều điều kiện về việc sử dụng này:

  • Phía bên tay trái của toán tử LIKE hoặc GLOB phải là tên của cột được lập chỉ mục có TEXT affinity.
  • Phía bên phải của LIKE hoặc GLOB phải là chuỗi ký tự hoặc tham số được liên kết với chuỗi ký tự không bắt đầu với ký tự đại diện.
  • Điều khoản ESCAPE không thể xuất hiện trên toán tử LIKE.
  • Các hàm dựng sẵn được sử dụng để triển khai LIKE và GLOB không được quá tải bằng cách sử dụng API sqlite3_create_function().
  • Đối với toán tử GLOB, cột phải được lập chỉ mục bằng cách sử dụng chuỗi đối chiếu BINARY được tích hợp sẵn. Đối với toán tử LIKE, nếu chế độ case_sensitive_like được bật thì cột phải được lập chỉ mục bằng chuỗi đối chiếu BINARY hoặc nếu chế độ case_sensitive_like bị tắt thì cột phải được lập chỉ mục sử dụng trình tự sắp xếp NOCASE tích hợp.
Các vấn đề liên quan