# Dictionary types: CRC vs keywords

在本文中，我们将讨论 Manticore Search 中可用的两种字典类型之间的差异。

[dictionary](https://docs.manticoresearch.com/latest/html/conf_options_reference/index_configuration_options.html#dict) 是一个索引组件，用于存储已索引的词语。最初使用的 '**crc**' 字典类型，其中词语会被替换为它们的校验和值，使用 CRC32 或 FVN64，具体取决于 Sphinx 是否编译了 **enable-id64**。在 Manticore 中仅使用 FVN64，因为已移除了 32 位 ID。

随着实时索引的引入，以及由于一些潜在缺点，需要一种替代的字典类型。在 Sphinx 2 中添加了 **'keywords'** 字典，它存储实际的词语并解决了 **'crc'** 的缺点（我们将在下文讨论），但它本身也有一些小问题。

实时索引（以及新推出的 [percolate 索引](https://docs.manticoresearch.com/latest/html/searching/percolate_query.html)）只能使用 **'keywords'** 类型，而 **'crc'** 类型仅适用于普通索引。普通索引需要 **'keywords'** 字典以允许转换为实时索引。一些较新的功能，如 [CALL QSUGGEST](https://docs.manticoresearch.com/latest/html/sphinxql_reference/call_qsuggest_syntax.html)，需要存储实际的词语，而这无法通过 **'crc'** 字典实现。

在未启用前缀/中缀的情况下：使用 **'keywords'** 字典的索引速度较慢。第一个原因是 '**keywords**' 在字典中存储整个词语（最多 127 个字符），而 **'crc'** 将任何词语折叠为 4 字节的哈希值。在索引的最后阶段，**'keywords'** 类型需要执行词语排序，这可能需要一些时间。简而言之，当使用 **'keywords'** 时，索引速度可能比使用 **'crc'** 慢 ***10%-40%***。当禁用前缀/中缀时，索引大小和搜索时间大致相同。

在启用前缀/中缀的情况下：**'crc'** 需要为子字符串构建额外的词语排列，因此在这种情况下可能比 '**keywords**' 更慢。当仅启用前缀时，**'keywords'** 字典在索引过程中没有额外的步骤。仅在启用中缀时，它会从词语中提取并收集三元组（用于 QSUGGEST）。由于额外的词语排列，'**crc**' 的索引大小可能比禁用前缀/中缀的版本膨胀超过 ***10 倍***。由于不需要存储额外的子字符串，使用 '**keywords**' 字典的索引大小与禁用前缀/中缀的版本相比不会增长。

对于通配符搜索，在 **'keywords'** 模式下，关键字会被扩展为索引中所有匹配通配符搜索的可能存储的词语。在某些边缘情况下，扩展可能涉及数千个词语，这会减慢查询速度。可以通过 '[expansion_limit](https://docs.manticoresearch.com/latest/html/conf_options_reference/searchd_program_configuration_options.html#expansion-limit)' 或避免有问题的扩展来限制此影响。'**CRC**' 没有这个问题，因为扩展是在索引时计算的，而不是查询时。虽然它在速度上有优势，但索引大小仍然是 '**crc**' 类型的主要问题。此外，无法使用特殊符号 `'?'` 和 `'%'` 进行通配符搜索，例如 `'t?st*'` 或 `'run%'`。

总体而言，'**keywords**' 类型是更好的选择，因为它提供了更多功能，并且如果需要使用通配符搜索，可以控制索引大小。然而，在某些情况下，通配符搜索可能需要特别注意。
虽然 '**crc**' 在 Sphinx 中被标记为已弃用，但我们决定移除此标记，因为 '**crc**' 在某些情况下仍然有用。

'**crc**' 的优势在于索引速度，这在使用需要适应特定时间窗口的增量索引时可能很重要。对于通配符搜索，'**crc**' 是一把双刃剑：虽然它不像 '**keywords**' 那样有潜在的性能问题，但使用时必须考虑其空间需求。
