如何分割mySQL全文表?

时间:2011-11-30 13:56:10

标签: mysql full-text-search

我有一个带有全文的mysql表。每天它的大小将增加30K数据项。我担心当数据大小增加到许多GB时,查询速度会降低。我的情况允许我将搜索限制为最近的一百万个数据项。

首先我尝试partitioning table,但mysql不同时支持fulltextpartition

http://dev.mysql.com/doc/refman/5.5/en/partitioning-limitations.html

有些朋友建议我使用其他dbms产品,例如sphinxsolroracle。但出于预算原因,我宁愿使用mySQL。 (原谅我的固执)。

那么,我该如何优化mysql全文表搜索?当数据量增大时,如何保持可接受的查询速度?

  1. 分桌? (然后使查询复杂)

  2. 仅限ID查询? SELECT * FROM table WHERE (MATCH (some_field) AGAINST ('+search_words' IN BOOLEAN MODE)) AND id>last_id-1000000 AND id<last_id Order By date DESC

  3. 另一个好建议?感谢。

1 个答案:

答案 0 :(得分:5)

这是一种处理问题的方法。它不是超级漂亮,但它会非常有效。

创建表的两个副本。拨一个类似text_current的内容,然后调用text_archive之类的内容。

将新到达的数据行加载到text_current。这样,您当前的数据将可用于搜索。

编写两个存储过程:一个称为copy_text的内容,用于从text_current中选择较旧的行并将其插入text_archive,另一个称为purge_text,用于删除来自text_current的旧行。然后,从mySql作业运行这两个存储过程。

如果我是你,我会每晚03:00运行一次copy_text工作,并复制前一天(午夜到午夜)任何时间到达的每件物品。

我会每周运行一次purge_text工作,并清除超过35天的text_current内的所有内容。 (每天30K记录获得100万条记录需要33.3天。)

这种将数据从当前表迁移到存档表的方法有一些方便的功能。

  1. 这是安全的 - 大多数记录都在当前和存档中 表。
  2. 这是确定性的 - 使用日期而不是ID可以让你 选择要精确存档的项目。
  3. 如果您需要,它提供了一个缓慢而有效的“搜索档案”功能 你的产品。
  4. 它保持当前数据表的大小 相对可行,同时允许您使用mySql的精细全文搜索功能。
  5. 效率很高 - 迁移的艰苦工作是每天一次完成,而不是通过查询中的ID号连续进行。
  6. 以下是record_date列为unix时间戳时按日期选择记录的方法。如果您在任何一天运行此操作,它将从前一天的午夜选择记录,直到当天午夜的但不包括记录。

    ...
    WHERE text_current.record_date >= UNIX_TIMESTAMP(DATE_SUB(CURDATE(), INTERVAL 1 DAY))
      AND text_current.record_date < UNIX_TIMESTAMP(CURDATE())
    ...
    

    一天中运行此查询的时间无关紧要,它始终在午夜到午夜运行。这就是CURDATE()的美丽 - 它意味着今天的午夜。 (NOW()表示现在;它就像CURDATE()但也有时间。但是你不希望这样,因为你想要在午夜到午夜进行归档。如果你使用{{ 1}}当您运行存储过程时,您会被小的不可预测性所困扰。

    (不要试图将NOW()运算符用于时间范围;它是包容性的,您希望时间范围的结束时间不包括在内。)

    同样,如果您要删除超过35天的所有内容,请执行此操作。

    BETWEEN

    看看这是怎么回事?当您进行归档和清除时,无论插入的时间长短,您总是根据插入的日期选择记录。这就是我所说的确定性。