2016-03-19 6 views
1

ファイルインデックスを作成しました。ファイルインデクサーはファイル名を指定されたテーブルに挿入するだけです。今私はファイル名を検索する最良の方法を検討しています。テーブルには100,000以上のファイルが存在する可能性があるため、パフォーマンスが重要です。大量のデータを照会するための最適な検索クエリと構造

ファイル名は、長さが10,20,50またはそれ以上のさまざまな長さにすることができます。少なくとも今のところ、テストデータセットには名前にスペースが含まれていません。ユーザーは部分検索を実行できます。たとえば、 '1001'を検索すると、名前が10_1001_20_30_40_50のファイルが返されます。

私の現在のテーブルの構造は:

CREATE TABLE `file` (
    `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, 
    `id_category` int(10) unsigned NOT NULL, 
    `filename` varchar(255) NOT NULL, 
    `file_ext` varchar(3) NOT NULL, 
    `date_added` timestamp NULL DEFAULT CURRENT_TIMESTAMP, 
    PRIMARY KEY (`id`,`id_category`), 
    KEY `idx_file_filename` (`filename`) USING BTREE, 
    KEY `fk_file_1_idx` (`id_category`), 
    FULLTEXT KEY `filename` (`filename`) 
) ENGINE=MyISAM AUTO_INCREMENT=24974 DEFAULT CHARSET=utf8; 

INSERT INTO `file` (`id`,`id_category`,`filename`,`file_ext`,`date_added`) VALUES (22474,14199,'095_98_1002_1003_148_98_1001_003','pdf','2016-03-19 19:02:12'); 
INSERT INTO `file` (`id`,`id_category`,`filename`,`file_ext`,`date_added`) VALUES (22475,14199,'095_98_1002_1003_148_98_1001_001','pdf','2016-03-19 19:02:11'); 

私はとの試合を()()を使用しようとしたが、それはあなたが、文字列にスペースを持っているし、したくない場合は、それは良い考えではありませんが判明しました文字列に検索文字列が含まれている場合はどうすればいいですか?

これは私に必要なものを返すことはありません。私が検討していること(。分文字列の長さのユーザーが提供することができます)3の長さにインポートする際、分割して、すべてのファイル名をFULLTEXTを使用することで、スペースで区切っ部品とそれらは、このようなクエリを使用します。私は残すことができます。もちろん、

SELECT * FROM `file` WHERE MATCH(filename) AGAINST ('100*' IN BOOLEAN MODE); 

ファイル名彼らは、オペレータように使用よう:

SELECT * FROM `file` WHERE filename LIKE '%100%' 

が、大規模なデータセットのためにLIKEを使用してについて多くの否定的な意見があります。私は、ファイル名にスペースを追加するという私の解決策が良い考えであるかどうか不思議です。 、スペースを必要とし、完全な「言葉」に(主に)あなたを制限し、「ショート」の言葉で非効率的な取得、「「ストップ言葉」など

LIKE '%100%を逃し、かかわらず非効率的なことからですFULLTEXTを使用しようとすると、

+0

エール1002のみを探しているか、長いシーケンス(1002_1003)も検索したいですか? –

+0

任意のクエリ> = 3文字 –

答えて

0

すべての行をテストする必要があります、あなたが必要なものです。

ファイル名のすべての関連部分が数字であることを暗示していますか?そして、部品全体をテストしたいだけですか?つまり、22_100_3322,10033ですが、2,10,00などでは検索されません。すべての場合、LIKEは正しく動作しません。例:101_1000LIKE '%100% 'によって捕捉されます。

ので、多分あなたは「転置インデックス」を構築したい10_1001_20_30_40_50について、あなたはテーブルに6行があります:101001など、およびいずれかの残りの列、またはいくつかのIDを( s)を入力してください。

+0

FTで大文字小文字を削除していただきありがとうございます。私は部品をテストし、部品が戻ってくるので、好きな人はOKです。それらの中のファイル名や部分は、英数字、さまざまな長さにすることができますので、あなたが提案した逆索引構造を使用することはできません。質問はまだ開いています - 私はLIKEを使用する必要があるように見えます。 –

0

大規模データのためのLIKEの使用についての否定的な意見が

チャンスはそれがあなたの場合には十分だろう、私が最初にそれをテストしますです。設定がたくさんあります

あなたが本当にスピードアップしたいのであれば、私は1つの選択肢を考えることができますが、メモリ、挿入時間、メンテナンス性、柔軟性、複雑さなどは犠牲になります。テーブルには、(擬似コード)のようになります。

CREATE TABLE Pref(
    prefix varchar(255) NOT NULL, 
    fileid bigint(20) unsigned NOT NULL, 

CONSTRAINT [PK_Pref] PRIMARY KEY CLUSTERED 
(
    prefix ASC, 
    fileid ASC 
)) 

、それは両方の列に主キーをクラスタ化されたであろうこの

'095_98_1002_1003_148_98_1001_003', 22474 
'95_98_1002_1003_148_98_1001_003', 22474 
'5_98_1002_1003_148_98_1001_003', 22474 
'_98_1002_1003_148_98_1001_003', 22474 
'98_1002_1003_148_98_1001_003', 22474 
... 
'03', 22474 
'3', 22474 

のようなデータを持っています。そうすれば接頭辞によって順序付けられ、接尾辞の検索'abcd%'に挿入語の検索'%abcd%'を変更することができます。クエリの形式は次のとおりです。

SELECT id, filename FROM `file` 
WHERE id IN (SELECT fileid FROM Pref WHERE prefix like 'abcd%') 

メインテーブルとの同期を維持するためにトリガを作成するだけで済みます。このテーブルの行を削除すると、接頭辞が指定されていないfileidの検索は避けるべきです。そうしないと、パフォーマンスが犠牲になります。

関連する問題