为模式匹配创建运算符类,如text_pattern_ops

时间:2012-12-11 07:40:56

标签: postgresql

我在text数据类型上创建了自己的比较运算符,它使用自然排序('1'&lt;'2'&lt;'10'&lt;'11'等),使用我的新运算符#<#,{ {1}},#<=##>#

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

#>=#

但是,当我使用新的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); 创建索引时,在text_natsort_ops的查询中不会使用此索引,因为在使用like时会执行此操作。

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

更新

以上似乎有效,所以问题无效。我真正的问题是我使用了一个类似的查询:

like

我还有另一个使用text_pattern_ops的索引,这是由规划者选择的,因为它似乎工作得更快。但是,由于select * from mytable where number like 'edi%' order by number using #<# limit 10 只有使用我的新操作的索引才有用...另一个索引返回太多结果,我需要限制子句可用于索引扫描。

3 个答案:

答案 0 :(得分: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 ...

答案 1 :(得分:2)

以上似乎有效,所以问题无效。我真正的问题是我使用了一个类似的查询:

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

我还有另一个使用text_pattern_ops的索引,这是由规划者选择的,因为它似乎工作得更快。但是,由于使用我的新操作仅使用索引的顺序将是有用的...另一个索引返回太多结果,并且我需要限制子句可用于索引扫描。

答案 2 :(得分: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允许对索引进行物理顺序搜索,这可能会成为可能,但只要索引只是逻辑顺序,我认为这不起作用。