@Saurabh Nanda:Tương tự như những gì bạn đã đăng, bạn cũng có thể tạo một hàm đơn giản để chuyển đổi mảng varchar thành chữ thường như sau:
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;
Lưu ý rằng tôi cũng đang cắt bớt các thẻ của khoảng trắng. Điều này có thể không cần thiết đối với bạn nhưng tôi thường làm vì sự nhất quán.
Thử nghiệm:
SELECT array_lowercase(array['Hello','WOrLD']);
array_lowercase
-----------------
{hello,world}
(1 row)
Như Saurabh đã lưu ý, sau đó bạn có thể tạo chỉ mục GIN:
CREATE INDEX ix_tags ON tagtable USING GIN(array_lowercase(tags));
Và truy vấn:
SELECT * FROM tagtable WHERE ARRAY['mytag'::varchar] && array_lowercase(tags);
CẬP NHẬT: Hiệu suất của WHILE
so với array_agg / unnest
Tôi đã tạo bảng 100K 10 phần tử text[]
mảng (chuỗi trường hợp hỗn hợp ngẫu nhiên 12 ký tự) và đã kiểm tra từng chức năng.
Hàm array_agg / unnest trả về:
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)
Hàm WHILE trả về:
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)
CẬP NHẬT 2: FOREACH
so với WHILE
Như một thử nghiệm cuối cùng, tôi đã thay đổi hàm WHILE để sử dụng 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'
Kết quả có vẻ giống với 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)
Mặc dù các bài kiểm tra của tôi không quá khắt khe, nhưng tôi đã chạy từng phiên bản một số lần và nhận thấy các con số là đại diện, cho thấy rằng phương thức SQL (array_agg / unnest) là nhanh nhất.