PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Membuat indeks case-insensitive pada array string Postgres

@Saurabh Nanda:Mirip dengan apa yang Anda posting, Anda juga dapat membuat fungsi sederhana untuk mengubah array varchar Anda menjadi huruf kecil sebagai berikut:

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;

Perhatikan bahwa saya juga memangkas tag spasi. Ini mungkin tidak perlu bagi Anda, tetapi saya biasanya melakukannya untuk konsistensi.

Pengujian:

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

Seperti yang dicatat oleh Saurabh, Anda kemudian dapat membuat indeks GIN:

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

Dan pertanyaan:

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

PERBARUI: Kinerja WHILE vs array_agg/unnest

Saya membuat tabel 100K 10 elemen text[] array (12 karakter string kasus campuran acak) dan menguji setiap fungsi.

Fungsi array_agg/unnest dikembalikan:

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)

Fungsi WHILE kembali:

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)

PEMBARUAN 2: FOREACH vs. WHILE Sebagai percobaan terakhir, saya mengubah fungsi WHILE untuk menggunakan 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'

Hasil tampaknya mirip dengan 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)

Meskipun pengujian saya tidak terlalu ketat, saya menjalankan setiap versi beberapa kali dan menemukan angka yang mewakili, menunjukkan bahwa metode SQL (array_agg/unnest) adalah yang tercepat.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Segarkan tampilan yang terwujud:Konkurensi, perilaku transaksional

  2. Iterasi melalui catatan PostgreSQL. Bagaimana cara mereferensikan data dari baris berikutnya?

  3. Daftar Periksa Kepatuhan SOx untuk PostgreSQL

  4. Hasilkan uuid di windows postgresql

  5. Migrasi SQL Server 2008 DB ke Postgres