【发布时间】:2016-03-19 18:58:59
【问题描述】:
我创建了文件索引器,它只是将文件名插入到指定的表中。现在我正在考虑搜索文件名的最佳方式。表中可能有 100000 多个文件,因此性能很重要。
文件名可以是不同的 - 长度为 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');
我尝试过使用 MATCH () AGAINST (),但结果表明,如果字符串中没有空格并且想要执行“如果字符串包含搜索”这样的操作,这不是一个好主意:
SELECT id, filename FROM `file` WHERE MATCH(filename) AGAINST ('1002*' IN BOOLEAN MODE);
这不会返回我需要的东西。我正在考虑的是通过拆分所有文件名来使用 FULLTEXT,同时导入由空格分隔的 3 个长度(用户可以提供的最小字符串长度)部分,它们使用如下查询:
SELECT * FROM `file` WHERE MATCH(filename) AGAINST ('100*' IN BOOLEAN MODE);
当然,我可以保留文件名并使用 LIKE 运算符:
SELECT * FROM `file` WHERE filename LIKE '%100%'
但是对于大型数据集使用 LIKE 有很多负面意见。我很好奇我在文件名中添加空格的解决方案是否是个好主意。
【问题讨论】:
-
Ale 您只寻找 1002,还是您也想搜索更长的序列 (1002_1003)?
-
可以是任何查询 >= 3 个字符
标签: mysql performance full-text-search sql-like