PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Създаване на нечувствителни към регистър индекси в масив от низове на Postgres

@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;

Обърнете внимание, че също изрязвам етикетите на интервалите. Това може да не е необходимо за вас, но аз обикновено го правя за последователност.

Тестване:

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);

АКТУАЛИЗАЦИЯ: Изпълнение на 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 спрямо 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) е най-бързият.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Django SearchVector с помощта на icontains

  2. ALTER TABLE за добавяне на нова колона на ограничено дисково пространство

  3. PostgreSQL 9.2 JDBC драйвер използва клиентска часова зона?

  4. Грешка в PostgreSQL:аргументът на низа на заявката на EXECUTE е нула

  5. Как да върна само работно време от резервации в PostgreSql?