为什么要在文本列上索引 text_pattern_ops ?

Iai*_*der 23 postgresql index collation pattern-matching

今天七周内的七个数据库向我介绍了每个操作员的索引。

您可以通过创建text_pattern_ops运算符类索引来为匹配先前查询的模式索引字符串,只要值以小写形式索引即可。

CREATE INDEX moves_title_pattern ON movies (
    (lower(title) text_pattern_ops);
Run Code Online (Sandbox Code Playgroud)

我们使用 是text_pattern_ops因为标题是文本类型。如果需要指数VARCHAR处理,字符,或名称,使用相关的OPS: ,varchar_pattern_opsbpchar_pattern_opsname_pattern_ops

我觉得这个例子真的很混乱。为什么这样做有用?

如果该列是文本类型,那么在用作搜索值之前,其他类型(varchar、char、name)不会被强制转换为文本吗?

该索引的行为与使用默认运算符的索引有何不同?

CREATE INDEX moves_title_pattern ON movies (lower(title));
Run Code Online (Sandbox Code Playgroud)

dez*_*zso 23

文档通常会为您提供此类问题的答案。就像在这种情况下一样:

运算符类 text_pattern_ops、varchar_pattern_ops 和 bpchar_pattern_ops 分别支持 text、varchar 和 char 类型的 B 树索引。与默认操作符类的不同之处在于,这些值严格逐个字符地进行比较,而不是根据特定于语言环境的排序规则进行比较。当数据库不使用标准的“C”语言环境时,这使得这些运算符类适用于涉及模式匹配表达式(LIKE 或 POSIX 正则表达式)的查询。例如,您可以索引一个 varchar 列,如下所示:

CREATE INDEX test_index ON test_table (col varchar_pattern_ops);
Run Code Online (Sandbox Code Playgroud)

请注意,如果您希望涉及普通 <、<=、> 或 >= 比较的查询使用索引,则还应使用默认运算符类创建索引。此类查询不能使用 xxx_pattern_ops 运算符类。(但是,普通的相等比较可以使用这些运算符类。)可以使用不同的运算符类在同一列上创建多个索引。

文档继续说:

如果您确实使用 C 语言环境,则不需要 xxx_pattern_ops 运算符类,因为具有默认运算符类的索引可用于 C 语言环境中的模式匹配查询。

您可以按如下方式检查您的语言环境(它可能是 UTF8 而不是“C”):

postgres=> show lc_collate;
 lc_collate
-------------
 en_GB.UTF-8
Run Code Online (Sandbox Code Playgroud)

  • @dezso:如果您看到使用普通 b 树索引的 `LIKE` 查询,那么数据库必须使用 `C` 语言环境。或者索引用`COLLATE "POSIX"`(或`COLLATE "C"`)定义并且查询指定匹配的[`COLLATION`](http://www.postgresql.org/docs/9.3/static/排序规则.html)。对于任何其他排序规则,索引的顺序与区域设置规则不匹配,因此不能用于模式匹配。 (6认同)
  • @StopHarmingMonica 您会得到正确的响应(并且没有错误),只是查询可能会变慢,无法使用索引。 (2认同)