インデックス作成を改善する
長さ(プレフィックス)ではなく、プレフィックスで直接注文することにより:
SELECT dialstring FROM call_routing
WHERE number like prefix || '%'
ORDER BY prefix DESC
LIMIT 1
なんで?
数値の選択された行はabcdef
プレフィックスになるためです。次のような数値になります。
ab abc abcd
したがって、それらをアルファベット順に並べると、長いものから短いものへのリストを取得するだけで十分であり、それが目的です。
また、次を使用してより強力なフィルターを取得できます。
prefix between 'a' and 'abcde'
. すべての接頭辞は、アルファベット順>=
で最も短い接頭辞になり、アルファベット順<=
で最も長い接頭辞になります。
したがって、次のように表現できます。
SELECT dialstring FROM call_routing WHERE
prefix between substr(number, 1, 1) and number -- range filter (use index)
AND number like prefix || '%' -- only relevant data (normal filter)
ORDER BY prefix DESC -- index will work
LIMIT 1
そしてもちろん、インデックスは列のプレフィックスになります。
すべてキャッシュしますか?
はい、お願いします。:)
アイテムはいくつありますか?巨大なリストでない場合は、メモリにロードします。
次に、TreeMap (接頭辞で並べ替えたい場合) または HashMap (最初に最も長い接頭辞を見つけて、毎回 1 文字ずつ減らして試行し続ける場合) を使用できます。どちらが良いでしょうか?範囲内にあり、条件a >> abcde
に一致しないプレフィックスの数によって異なります (例による)。like
abbde
エントリー数が少ない場合
接頭辞 desc でソートされた配列を使用できます。
be
b
abcde
abbbc
abd
ab
適切なプレフィックスArrays.binarySearch(T[], T key, Comparator<T>)
を見つけるには、電話がそこにあるかどうかを確認します ( abcde
)。よかったら。そうでない場合は、次の時点まで先に進みます。
- you find a prefix (OK, this is the winner)
- it doesn't start with the same char (there are no prefix)
このようにして、範囲をトラバースしabcde >> a
、最初のプレフィックス (可能な限り長い) を見つけます。
良いもの
TREEを作っています(名前はわかりません)。各ノードが文字 (この場合は数字) のみを保持するツリーを作成します。
0 // represents 0
->
2 // represents 02
-> 1 // represents 021
-> 3 // represents 023
->
4 // represents 04
したがって、最長のプレフィックスを探すときは、ツリーのできるだけ深い部分に到達しようとします。
Node n = root;
for (char c: number) {
if ((child = n.hasChild(c)) != null)
{
prefix += c;
n = child;
}
else
break;
}
を作成するには が必要です
class Node
{
int digit;
Map<Integer, Node> childs = new HashMap<Integer, Node>(); // or a 10 bucket array :)
YourInfo info;
}
そして、構造を作成するために:
findOrCreateNode(prefix).setInfo(info);
ここで、findOrCreateNode は前と同じですが、ノードが見つからない場合は... ノードを作成します ( n.put(c, new Node(c))
)。