用于NxM字符串搜索的mySQL优化

时间:2014-11-20 12:02:55

标签: mysql optimization indexing

对于通用主题感到抱歉,但我想不出更好的事情:(

假设我有一些固定字符串(名为s1,s2,... sn,不超过5或6,示例中为4),我必须检查已存在的表,其中包含几个VARCHAR(50 )字段(称为t1,t2,t3,......不超过5,但在示例中为4)。 简单查询看起来像这样:

SELECT id FROM tbl WHERE (s1 = t1) or (s1 = t2) or (s1 = t3) or (s1 = t4) OR
                         (s2 = t1) or (s2 = t2) or (s2 = t3) or (s2 = t4) OR
                         (s3 = t1) or (s3 = t2) or (s3 = t3) or (s3 = t4) OR
                         (s4 = t1) or (s4 = t2) or (s4 = t3) or (s4 = t4) OR 
                         (s5 = t1) or (s5 = t2) or (s5 = t3) or (s5 = t4)  

起初,当我创建t1,t2时,我正在考虑生成一个连接所有t1 + t2 + t3 + t4的大字符串...因为它在创建它时不会“花费时间”,然后在mySQL中使用某种“substr”来查找字符串。类似的东西(再次,我不知道mySQL语法)

SELECT id FROM tbl WHERE (s1 in conc) or (s2 in conc) or (s3 in conc) or (s4 in conc) or (s5 in conc)

真正的问题是表格中的元素数量。 “tbl”有大约50k个元素,我必须用不同的s1 / s2 / s3 / s4 / s5运行这个查询大约10k次(我也从数据库中获取它们,但是我在内存中读取它们以便将事情搞定)

内存大小应该不是问题:每行大约250字节长,因此RAM中的表总共大约为12Mb。将它加载到数组中并直接在RAM中进行搜索是否有意义?此时,是否有办法强制mySQL服务器始终将一个表保留在RAM中,因为它知道它不会增长太多而且12Mb与它节省的时间相比是一个非常小的内存量? (我正在运行PHP的查询。)

当然,我不在乎查询是愚蠢还是丑陋或不优雅。我正在寻找尽可能快的东西,因为我必须运行该查询大约500k次。对索引等方面的任何建议也是受欢迎的:)

PS:现在我想在凌晨4点在CRON工作中每24小时做一次,但能够按需完成并且不停服10分钟就可以了......(一毫秒)每个是500s,因此几乎9分钟的100%CPU时间......)

1 个答案:

答案 0 :(得分:1)

如果您需要性能,则需要使用索引。不幸的是,or往往会阻碍索引的使用。

以下是一种解决方案。在每个列上创建一个索引 - 独立,因此每个列都有一个索引" t"领域。然后构造常量字符串,以便使用in。将查询短语为:

SELECT id FROM tbl WHERE t1 in (s1, s2, s3,  . . .) 
UNION
SELECT id FROM tbl WHERE t2 in (s1, s2, s3,  . . .) 
UNION
SELECT id FROM tbl WHERE t3 in (s1, s2, s3,  . . .) 
UNION
SELECT id FROM tbl WHERE t4 in (s1, s2, s3,  . . .) 
UNION
SELECT id FROM tbl WHERE t5 in (s1, s2, s3,  . . .) 

MySQL应该为每个子查询使用索引。删除重复项会导致union开销。据推测,这可以通过不同领域的比较来实现。

另一种方法是将MATCH() . . . AGAINST与全文索引一起使用。您可以阅读有关这些here的更多信息。

相关问题