9

我在使用自然排序('1' < '2' < '10' < '11' 等)的文本数据类型上创建了自己的比较运算符,使用我的新运算符#<#、和。#<=##>##>=#

现在我将它们放入一个运算符类中,以便能够在它们上创建索引,如下所示:

CREATE OPERATOR CLASS text_natsort_ops
   FOR TYPE text USING btree AS
   OPERATOR 1  #<#,
   OPERATOR 2  #<=#,
   OPERATOR 3  =,
   OPERATOR 4  #>=#,
   OPERATOR 5  #>#,
   FUNCTION 1  bttext_natsort_cmp(text, text);

但是,当我使用我的 new 创建索引时text_natsort_ops,这不会在涉及的查询中使用,like因为它在text_pattern_ops使用时完成。

如何声明我的运算符类以允许like使用我的索引?

更新:

以上似乎有效,因此问题无效。我真正的问题是我使用了如下查询:

select *
  from mytable
 where number like 'edi%'
 order by number using #<#
 limit 10

而且我还有另一个使用 text_pattern_ops 的索引,它是由计划者选择的,因为它似乎工作得更快。但是,因为order by ... using只有使用我的新操作的索引才有用......另一个索引返回太多结果,我需要限制子句可用于索引扫描。

4

3 回答 3

3

在https://github.com/dimitri/prefix查看 PostgreSQL 前缀扩展 他们也定义了自己的OPERATOR CLASS并告诉 PostgreSQL 为某些运算符使用特殊的 GIST 索引,也许你需要类似的东西?

CREATE OPERATOR CLASS gist_prefix_range_ops DEFAULT FOR TYPE prefix_range USING gist ...
于 2013-06-05T21:51:53.540 回答
2

以上似乎有效,因此问题无效。我真正的问题是我使用了如下查询:

select *
  from mytable
 where number like 'edi%'
 order by number using #<#
 limit 10

而且我还有另一个使用 text_pattern_ops 的索引,它是由计划者选择的,因为它似乎工作得更快。但是,由于 order by ... 仅使用我的新操作的索引将很有用...另一个索引返回太多结果,我需要 limit 子句可用于索引扫描。

于 2013-06-07T13:32:47.930 回答
1

我不认为这是可能的。你必须考虑你在做什么以及为什么这行不通。您将拥有支持前缀搜索的索引或支持自然数范围搜索的索引。您不能拥有同时支持两者的 btree 索引。

考虑类似的事情:

SELECT * FROM foo
WHERE bar like '10%'
ORDER BY bar USING #>#;

您的问题是您的两个索引将没有匹配的顺序。与 LIKE 一起使用的索引将变为 101、101000、101001 等,而用于订购的索引将变为 10、11、12、13... 101、102、103、104、105、106、107、108、 109, 110, 111, ...

因为您的排序需要不同的搜索顺序,所以无法对两者使用相同的索引。在某些时候,如果 PostgreSQL 允许对索引进行物理顺序搜索,这可能会成为可能,但只要索引是逻辑顺序,我认为这是行不通的。

于 2013-04-18T10:12:38.200 回答