10

このようなスキーマを使用してテーブルを作成します。

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

これで、テーブルには約450,000行のレコードがあります。ipod4で以下のLikeステートメントを使用すると、パフォーマンスが良くありません。select * from wordIndex where word like'test acces%'; Explain出力を使用します。

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|

パフォーマンスを向上させるために、追加の転置インデックスを作成する必要があるかもしれません...?よろしくお願いします!

4

3 に答える 3

13

インデックスをlike作成し、ほとんどのデータベースではうまくいきません。インデックスが使用されるため、可能であれば、クエリを範囲クエリとして書き直すのが最善の策です。

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

(中括弧は「z」の直後のASCII文字です。)

単語の先頭にあるパターン(たとえば「%test」)を探している場合は、全表スキャンに辞任する必要があるかもしれません。

編集:

インデックスとlike*do`は、パターンが定数で始まる場合、ほとんどのデータベースで最近うまくいくので、次のことができます。

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

ただし、SQLiteについて100%確信が持てないので、実行プランをチェックして、インデックスが使用されているかどうかを確認してください。

于 2012-12-27T15:11:58.077 に答える
5

これを試して:

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

「〜」は最大のASCII記号です。

于 2012-12-27T15:16:37.593 に答える
2

ゴードン・リノフとは少し違う答えがありますが、同じアプローチです。

'test acces'に続く文字を保持したい場合は、これを試してください。

SELECT * FROM wordIndex
WHERE word > 'test acces' AND word < 'test accet';
于 2013-01-18T13:13:13.527 に答える