在 Postgres 字符串数组上创建不区分大小写的索引

2023-12-29

我正在使用一个varchar[]Postgres 9.2 中的列(varchar 数组)用于存储一些标签。在按标签检索行时,我希望查询不区分大小写。但是,我想保留在 UI 中显示的大小写(因此我不能只将所有内容存储为小写)。

所以,我的问题是如何在 Postgres 中通过 varchar 数组创建不区分大小写的索引?一种可能的方法是在列上创建功能性 GIN 索引。如何做到这一点?还有其他方法吗?


@Saurabh Nanda:与您发布的内容类似,您还可以创建一个简单的函数将 varchar 数组转换为小写,如下所示:

CREATE OR REPLACE FUNCTION array_lowercase(varchar[]) RETURNS varchar[] AS
$BODY$
  SELECT array_agg(q.tag) FROM (
    SELECT btrim(lower(unnest($1)))::varchar AS tag
  ) AS q;
$BODY$
  language sql IMMUTABLE;

请注意,我还修剪了空格标签。这对你来说可能不是必需的,但我通常这样做是为了保持一致性。

Testing:

SELECT array_lowercase(array['Hello','WOrLD']);
 array_lowercase 
-----------------
 {hello,world}
(1 row)

正如 Saurabh 所指出的,您可以创建一个 GIN 索引:

CREATE INDEX ix_tags ON tagtable USING GIN(array_lowercase(tags));

并查询:

SELECT * FROM tagtable WHERE ARRAY['mytag'::varchar] && array_lowercase(tags);

UPDATE:的表演WHILE与 array_agg/unnest 比较

我创建了 100K 10 元素的表text[]数组(12 个字符的随机混合大小写字符串)并测试每个函数。

array_agg/unnest 函数返回:

EXPLAIN ANALYZE VERBOSE SELECT array_lowercase(data) FROM test;
                                                       QUERY PLAN                                                       
------------------------------------------------------------------------------------------------------------------------
 Seq Scan on public.test  (cost=0.00..28703.00 rows=100000 width=184) (actual time=0.320..3041.292 rows=100000 loops=1)
   Output: array_lowercase((data)::character varying[])
 Total runtime: 3174.690 ms
(3 rows)

WHILE 函数返回:

EXPLAIN ANALYZE VERBOSE SELECT array_lowercase_while(data) FROM test;
                                                       QUERY PLAN                                                       
------------------------------------------------------------------------------------------------------------------------
 Seq Scan on public.test  (cost=0.00..28703.00 rows=100000 width=184) (actual time=5.128..4356.647 rows=100000 loops=1)
   Output: array_lowercase_while((data)::character varying[])
 Total runtime: 4485.226 ms
(3 rows)

更新2: FOREACH vs. WHILE作为最后的实验,我将 WHILE 函数更改为使用 FOREACH:

CREATE OR REPLACE FUNCTION array_lowercase_foreach(p_input varchar[]) RETURNS varchar[] AS $BODY$
DECLARE
    el text;
    r varchar[];
BEGIN
    FOREACH el IN ARRAY p_input LOOP
        r := r || btrim(lower(el))::varchar;
    END LOOP;
    RETURN r;
END;
$BODY$
  language 'plpgsql'

结果似乎类似于WHILE:

EXPLAIN ANALYZE VERBOSE SELECT array_lowercase_foreach(data) FROM test;
                                                       QUERY PLAN                                                       
------------------------------------------------------------------------------------------------------------------------
 Seq Scan on public.test  (cost=0.00..28703.00 rows=100000 width=184) (actual time=0.707..4106.867 rows=100000 loops=1)
   Output: array_lowercase_foreach((data)::character varying[])
 Total runtime: 4239.958 ms
(3 rows)

尽管我的测试并不严格,但我确实多次运行每个版本并发现这些数字具有代表性,这表明 SQL 方法 (array_agg/unnest) 是最快的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Postgres 字符串数组上创建不区分大小写的索引 的相关文章

随机推荐

  • 如何在java中使用jmap分析堆转储

    我正在使用以下命令创建堆转储 jmap dump file DumpFile txt
  • 在 Rails 中播种数据库的最佳方法是什么?

    我有一个 rake 任务 可以在我的 Rails 应用程序中填充一些初始数据 例如 国家 州 移动运营商等 我现在设置的方式是 我在 db fixtures 的文件中有一堆 create 语句 以及一个处理它们的 rake 任务 例如 我的
  • 有什么区别

    有什么区别 a and a 一个使用括号 另一个不使用 但是使用其中一个有什么区别 什么是 正确 的选项 如果我不使用任何会发生什么href属性 据我所知 在javascript中 使用something someFunc 将该函数的返回值
  • VS2015安装一直挂起

    我尝试在完全更新的 Windows 8 1 上安装 vs2015 CTP5 但安装在 LocalESPCui for en us Dev12 步骤上一直挂起 大约一个小时 我正在使用通过PowerISO安装的 iso 如何才能完成安装 安装
  • 设置Surface View的背景颜色

    我想为相机表面视图的表面视图设置背景颜色 我在用this https stackoverflow com questions 8104789 how to set backgroundcolor to a surfaceview in an
  • 从 MySQL 表中删除制表符、换行符等

    我需要从 MySQL 表的字段中删除多个空格 制表符 换行符 回车符 换页符或垂直制表符 Here 如何使用Java删除字符串中的重复空格 http tab 20new 20line 20carriage 20return 20form 2
  • ZendFramework - 如何从控制器添加 ->HeadScript()?

    我有一个情况 我需要将控制器中的 Javascript 添加到已经有 HeadScript 的布局中 如何从控制器做到这一点 e g this gt view gt HeadScript gt appendScript 这是控制器 两者都不
  • Grails 与 Spring [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 任何人都可以解释一下 对于超过 500 个数据库表的企业 Java Web 应用程序来说 什么是更好的选择 我们应该使用 Grails 或 Go
  • 尝试使用 BigQuery 计算 EMA(指数移动平均线)

    我正在尝试计算股票价格的指数移动平均线 EMA 我正在使用一个公式从该网站计算 EMA http www iexplain org ema how to calculate http www iexplain org ema how to
  • 如何检测何时按下热键(快捷键)

    How do I detect when a shortcut key such as Ctrl O is pressed in a WPF independently of any particular control I tried c
  • Google 附近的消息 - 取消设备之间的初始链接

    我正在构建一个应用程序来测试 Google 附近消息 API 对于该测试 我使用 DISTANCE TYPE EARSHOT 根据这个线程附近 API 的 Strategy DISTANCE TYPE EARSHOT 似乎并不限制消息接近度
  • 网络聊天或 Skype 上不显示 Rich Card 附件

    Rich Card 附件未在网络聊天或 Skype 上显示 但在模拟器上显示正常 如果我使用 ContentType ContentURL 附件包含正确的数据和属性并且工作正常 但如果我使用丰富的卡片附件 它们不会显示在网络聊天或 Skyp
  • 使用 IIS 在同一服务器上为同一站点运行 node.js 和 Web API

    我正在寻找慢慢转换Node js应用程序转移到ASP NET WebAPI 2 0 我目前正在使用IIS并会坚持IIS 因此 我想将它们托管在同一台服务器上 但将一些 URI 定向到新平台 我将如何在web config 目前的web co
  • 使用 ipython 在 pycharm 中获得真正的代码完成

    许多 python IDE 都声称提供代码完成 代码洞察 PyCharm 就是其中之一 然而 在我看来 提供的代码完成是极其有限的 让我举个例子来让大家清楚地了解一下 import numpy as np m np random rando
  • 主线程超过设定的睡眠时间

    public static AtomicInteger num new AtomicInteger 0 public static void main String args throws Throwable Runnable runnab
  • 沿着 CGPath 的渐变

    我正在绘制一个几乎完整的圆弧 CGContextSetFillColorWithColor context UIColor whiteColor CGColor CGMutablePathRef path CGPathCreateMutab
  • jquery ajax 帖子已取消

    我想跟踪一组页面上一组 UI 组件上的鼠标单击事件 为此 我使用以下 jquery ajax 调用 修剪掉 u 1 Ajax调用将添加点击日志记录 myClickLogger endpoint path to my logging endp
  • 静态对象上的shared_ptr好吗?

    我想知道静态对象上的智能指针是否合理 例如 假设我有一些静态资源 并且想要将该静态资源的引用传递给需要这些资源使用的其他对象 一种方法是使用指向该资源的原始指针 但现在我想知道智能指针 shared ptr 是否是更好的方法 如果是 如何正
  • 如何在 MySQL 中将持续时间值存储为 TIME 数据类型?

    我需要以分钟 秒为单位存储歌曲持续时间 我需要使用 TIME 但是当我编写 INSERT 语句时如何引用某个持续时间 我在表中的数据类型已经是 TIME 我应该只使用 STR TO DATE 字符串值 4 29 吗 首先 看一下这里 htt
  • 在 Postgres 字符串数组上创建不区分大小写的索引

    我正在使用一个varchar Postgres 9 2 中的列 varchar 数组 用于存储一些标签 在按标签检索行时 我希望查询不区分大小写 但是 我想保留在 UI 中显示的大小写 因此我不能只将所有内容存储为小写 所以 我的问题是如何