普通索引的文本数据是不可变的,这意味着要刷新数据,我们需要执行完整的重新索引。在许多情况下,重新索引可能需要很长时间。为此,使用了 main+delta schema 。
该概念假设一个大型索引,它保存了某个时间点的数据快照,以及一个较小的索引,它保存了从快照时间到更近期的更改(delta)。由于后者较小,可以更频繁地重新索引。delta 更改可以是新记录、更新或删除的记录。更新或删除的记录会引入一个问题:当引擎在两个索引中搜索时,它不知道主索引中的记录是否已过时。这会导致继续显示实际上已被删除的记录,或者(在更新记录的情况下)包含来自 delta 索引的旧版本记录,而不是更新的版本。
为了解决这个问题,引入了 kill-list 功能。kill-list 定义了在 delta 索引中的一组文档 ID,它告诉引擎这些记录应该在之前的索引中被忽略。
sql_query_killlist = \
SELECT id FROM documents WHERE updated_ts>=@last_reindex UNION \
SELECT id FROM documents_deleted WHERE deleted_ts>=@last_reindex
在此示例中,我们将 kill-list 中包含自 @last_reindex(上次主索引发生的时间)以来更新的文档 ID,以及删除的文档 ID。documents_deleted 表可以在删除 documents 中的记录时手动填充,或者使用触发器。
需要记住关于 kill-list 的一个重要事项是,删除操作是按照它们在声明中的顺序在前面的索引上进行的。
如果你在索引上执行顺序搜索,delta 必须在 主索引 之后。
mysql> SELECT * FROM main,delta WHERE MATCH('...');
如果使用多个 delta(如 delta_daily, delta_hourly),顺序应该是 main,delta_daily,delta_hourly,而不是 main,delta_hourly,delta_daily。
kill-list 也用于本地分布式索引,这种情况下索引的定义顺序同样重要,即使我们对本地索引进行并行处理(使用 dist_threads > 0):
index dist
{
local = main
local = delta
}