mysql-根据关键字过滤列表,包括列表和关键字>;2000万条记录(慢)

mysql-根据关键字过滤列表,包括列表和关键字>;2000万条记录(慢),mysql,Mysql,我有两个表,都有超过2000万条记录;表1是一个术语列表,表2是一个关键字列表,这些关键字可能出现在这些术语中,也可能不出现在这些术语中。我需要识别包含关键字的术语。 “term”字段是一个VARCHAR(320),而“keyword”字段是一个VARCHAR(64) 我目前的策略是: SELECT table1.term, table2.keyword FROM table1 INNER JOIN table2 ON table1.term LIKE CONCAT('%', table2.k

我有两个表,都有超过2000万条记录;表1是一个术语列表,表2是一个关键字列表,这些关键字可能出现在这些术语中,也可能不出现在这些术语中。我需要识别包含关键字的术语。
“term”字段是一个VARCHAR(320),而“keyword”字段是一个VARCHAR(64)

我目前的策略是:

SELECT table1.term, table2.keyword FROM table1 INNER JOIN table2 ON table1.term 
LIKE CONCAT('%', table2.keyword, '%');
这不起作用,它需要时间。
这不是服务器,afaict(请参阅注释)

我如何重写它,使它在一天内运行

我喜欢内存中的表,或者改用innodb,使缓冲池足够大以容纳这两个表。不幸的是,每个mysql线程都绑定到一个cpu,但我有4个内核(加上超线程,“8”);如果我能分配工作量,那就太好了

注:

  • 关于服务器优化:两个表都是myisam,并且在匹配字段上有唯一的索引;myisam密钥缓冲区大于两个索引文件大小之和,并且它甚至没有被完全占用(
    key\u blocks\u unused
    很大);该服务器是一个2x双核xeon 2U beast,具有快速sas驱动器和8G ram,针对mysql工作负载进行了调整

  • 我只记得我只索引“term”字段的前80个字符(以节省磁盘空间);不确定这是伤害还是帮助

  • MySQL 5.0.32,Debian Lenny x86_64


  • 首先,您应该规范化您的模式:您应该创建第三个表来保持
    术语
    关键字
    之间的关系,方式是
    术语id关键字id
    ,而不是像现在这样做-在由空格分隔的字符字段中

    您想要设置全文索引,然后对其进行搜索。现在,您的唯一索引可能根本无助于搜索(因为搜索中的前导“%”)

    这意味着,它几乎肯定会对表2中的每个项目运行表1的完整扫描。称之为极度低效是一种很好的说法。构建全文索引有点慢(虽然可能比您现在正在做的要快),但一旦完成,搜索应该会快得多


    至于如何使用全文索引:虽然MySQL有内置的全文索引功能,但我怀疑它能帮你很多忙——有2000万行,但它的性能相当差(至少在我的经验中是这样)。要设置的工作要多一些,但更有可能为您提供足够的性能

    term上的索引不会在类似于您的查询中使用,所以这无关紧要。因为你基本上是在浏览每个关键字,索引也不重要。正则表达式会比LIKE更快吗?为什么是正则M:M关系的全文?问题是对术语/关键字关系的初始分析,而不是它们的存储。事实上,我正在将结果存储在第三个表中。如果您愿意听从我的建议,您可以快速选择您要求的数据。谢谢您的建议,zerkms;我已经安排好了。不幸的是,最初的查询仍然在运行(3天了),所以我仍然需要帮助。我正在考虑编写一个脚本来执行分析,这样我就可以更好地控制并行化等。