最も効率的な方法を解決するためのガイダンスを探しているという問題があります。サイズが 3 文字から 70 文字までの 2 億文字列のデータがあります。文字列は、文字の数字と、ダッシュやアンダースコアなどのいくつかの特殊文字で構成されます。文字列全体または文字列内の任意の部分文字列をすばやく検索できる必要があります (部分文字列の最小サイズは 3 です)。ここでは、1 秒未満と定義されています。
これでの最初のカットとして、次のことを行いました。
38 個のインデックス ファイルを作成しました。インデックスには、特定の文字で始まるすべての部分文字列が含まれています。最初の 4MB には 100 万個のハッシュ バケットが含まれます (ハッシュ チェーンの開始)。インデックスの残りの部分には、ハッシュ バケットからのリンク リスト チェーンが含まれます。私のハッシュは非常に均等に分散されています。100 万個のハッシュ バケットが RAM に保持され、ディスクにミラーリングされます。
文字列がインデックスに追加されると、重複しない (それ自体の中で) 3-n 文字の部分文字列に分割されます (n が文字列-1 の長さの場合)。たとえば、"apples" は "A" インデックスに pples,pple,ppl,pp として格納されます (部分文字列は "L" および "P" インデックスにも格納されます)。
検索/追加サーバーは (C++ で) デーモンとして実行され、チャンピオンのように機能します。通常の検索時間は 1/2 秒未満です。
問題はプロセスのフロントエンドにあります。通常、一度に 30,000 個のキーを追加します。プロセスのこの部分には永遠に時間がかかります。ベンチマークとして、180,000 個の可変長キーの空のインデックスへの読み込み時間は約 3 時間半です。
このスキームは、ロード時間が非常に長いことを除いて機能します。
最適化に夢中になる (またはしようとする) 前に、この問題を解決するためのより良い方法があるかどうか疑問に思っています。前後のワイルドカード検索 (つまり、DBMS の '%ppl%' のような文字列) は、このような大規模なデータセットでは驚くほど遅くなります (たとえば、MySQL では数時間のオーダー)。したがって、DBMS ソリューションは問題外のようです。通常の単語ではなく、実際の単語で構成されているかどうかに関係なく文字列を扱っているため、全文検索は使用できません。