MySQL查询与MATCH和AGAINST挂起

时间:2016-05-04 15:57:24

标签: php mysql sql database

我有多个CURL脚本,可以将许多内部公司站点的数据收集到共享数据库中。每个脚本都被称为"实例"。数据以记录的形式添加到数据库中。每条记录都有多个"字段",它们是键 - >值对。由于每个记录的键都是动态的,并且可以是任何记录(即使在同一个实例上),因此它们不会硬编码到MySQL表中。

所以有这些表:

  1. 记录 - 包含记录列表,每个记录都与一个实例相关联
  2. record_fields - 包含与记录相关联的字段列表
  3. record_fields_labels - 基本上是标签列表。这存储在数据库中以节省空间(即,而不是record_fields有数千个具有标签的字段"文章日期",它们都将具有数字8,这是record_labels上的记录的ID具有"文章日期"作为其价值)。
  4. record_fields和record_fields_labels都是MyISAM表,其上有一个FULLTEXT索引"内容" (record_fields中包含实际数据的列)和"标签" (record_fields_labels中具有标签名称的列)。

    数据库有数百万条记录 - 每个记录数乘以... 当实例运行时,为了检查数据库中是否已存在记录,它们执行以下SQL查询:

    SELECT r.id FROM records r INNER JOIN record_fields rf ON rf.record_id=r.id INNER JOIN record_fields_labels as rfl ON rf.label=rfl.id WHERE r.instance IN (120) AND MATCH (rf.content) AGAINST ('"http://xxxx.xxxx/xxx.xxx.xxx"' IN BOOLEAN MODE) AND MATCH (rfl.label) AGAINST ('"Article URL"' IN BOOLEAN MODE) GROUP BY r.id
    

    在此示例中,http://xxxx.xxxx/xxx.xxx.xxx是脚本检查系统中是否已存在的文章的URL。

    TL; DR

    问题在于:当数据库很大(即数百万条记录/记录字段)时 - 上述查询就会挂断。查询将运行,甚至数小时,没有明显的原因。此相同的查询用于搜索收集的数据中的项目,这些项目似乎有效(或直到最近才工作)。

    我想要的只是让它显示这样的记录是否存在。 它似乎不是一个索引问题,但与MATCH AGAINST有关。我宁愿避免使用所有内容的附加索引(除了FULL TEXT索引)来节省空间。

    有人知道造成这种挂断问题的原因吗?

    由于

1 个答案:

答案 0 :(得分:0)

看起来您正在使用FULL TEXT索引,而不是必须使用,特别是对于您的标签。如果这些很简单且定义得很好,那么正常指数就可以了。例如,如果您需要区分“文章日期”和“博客日期”,请使用一个字段作为内容类型,一个字段作为数据类型。

当您使用MATCH AGAINST ...在BOOLEAN模式中搜索短语时,您实际上是以相同的顺序搜索相同的单词,而不是完整的字符串..请参阅DOCS

在您的字段内容中搜索“http://xxxx.yyy/www.zzz.mmm”实际上会匹配“http:xxxx.yyy www!zzz mmm?yes please,more content”中的某些内容,并假设您的全文最小字长为3或更少。对于性能和逻辑,这不是正确的索引。

我会认真考虑更改您的数据结构,这样您就不会在网址和标签上放置FULL TEXT索引。与避免使用普通索引相比,这可能会为您节省更多空间。