15

私はsqliteにliketonoのインデックスを使用させようとしてきました。私はnocaseを照合しようとしましたが、それでも運がありません。誰もがsqliteにインデックスを打つようなことをさせる方法についてのアイデアを持っています。前もって感謝します

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%' 
4

4 に答える 4

19

sqliteメールリストからの引用(http://www.mail-archive.com/sqlite-users@sqlite.org/msg27760.html)

LIKEは、デフォルトでは大文字と小文字を区別しません。インデックスを使用するには、インデックスで大文字と小文字を区別しないようにする必要があります。

CREATE INDEX test_name ON test(name COLLATE NOCASE);

または、LIKEで大文字と小文字を区別します。

PRAGMA case_sensitive_like = 1;

于 2012-10-21T04:43:25.590 に答える
4

SQLite 3.6.23.1では、上のインデックスtestが使用されます。

> 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

SQLite 3.7.15の開発バージョンでは、test'sとtest3'sの両方のインデックスが使用されます(インデックスonは、検索ではなくスキャンtest2に使用されます)。

> 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)

したがって、答えはSQLiteを更新することです。

于 2012-10-21T10:12:29.810 に答える
1

ドキュメントから:

LIKEまたはGLOB演算子で構成される用語は、インデックスを制約するために使用される場合があります。この使用には多くの条件があります。

  • LIKEまたはGLOB演算子の左側は、TEXTアフィニティを持つインデックス付き列の名前である必要があります。
  • LIKEまたはGLOBの右側は、文字列リテラルか、ワイルドカード文字で始まらない文字列リテラルにバインドされたパラメータのいずれかである必要があります。
  • ESCAPE句はLIKE演算子には表示できません。
  • LIKEおよびGLOBの実装に使用される組み込み関数は、sqlite3_create_function()APIを使用してオーバーロードされていない必要があります。
  • GLOB演算子の場合、組み込みのBINARY照合シーケンスを使用して列にインデックスを付ける必要があります。
  • LIKE演算子の場合、case_sensitive_likeモードが有効になっている場合は、BINARY照合シーケンスを使用して列にインデックスを付ける必要があります。case_sensitive_likeモードが無効になっている場合は、組み込みのNOCASE照合シーケンスを使用して列にインデックスを付ける必要があります。
于 2017-03-22T20:33:06.603 に答える
0

私も同じ問題を抱えていorg.xerial/sqlite-jdbc "3.25.2"ます。単純なTEXTベースのインデックスはLIKE演算子では使用されていません。しかし、私が置く=と、インデックスが使用されます。私のテーブルスキーマ:

 create table if not exists test (ID INTEGER PRIMARY KEY, VALUE TEXT NOT NULL)
 create index test_idx on test(value)
 insert into test (ID,  VALUE) values (1, 'gold bangles')
 insert into test (ID,  VALUE) values (2, 'gold bandana')
 insert into test (ID,  VALUE) values (2, 'gold bracelet')

 explain query plan select * from test where value='gold bandana'

 Output:
 0|0|0|SEARCH TABLE test USING COVERING INDEX test_idx(VALUE=?)

 explain query plan select * from test where value like 'gold%'

 Output:
 0|0|0|SCAN TABLE test
于 2019-10-08T06:01:53.340 に答える