그건 꽤 무시 무시한 스키마입니다. 이를 변경하여 최상의 결과를 얻으려면 여러 값을 다음에 저장하십시오.
- 일반 관계형 하위 테이블;
- Arrays; 또는
당신이 원하는, 그리고 자식 테이블에 대한 일반 B-tree 인덱스를 통해 (색인, 그리고 GIST 또는 GIN 인덱스를 통해 결정하는 매우 간단하고 제정신 SQL 표현식을 사용할 수 있도록 모두의
hstore
배열 및 hstore의 경우) 큰 테이블에서 더 나은 성능을 제공합니다.
분명히 그대로 가능하지만 성능은 비참 할 것입니다. 한 가지 방법은 regexp_split_to_array
을 사용하여 열을 배열로 변환 한 다음 array operators을 사용하여 겹침을 테스트하는 것입니다.
확장 테스트 세트를 사용하는 this SQLFiddle demo을 참조하십시오. 사용자가 문제를 설명하기에 충분하지 않았기 때문입니다.
원하는 질문에서 분명하지 않기 때문에 "모든 세트가 열에 나타납니다"(%%
)와 "모든 세트가 열에 나타남"(@>
)을 보았습니다.
설정 :
CREATE TABLE test(gah text);
INSERT INTO test(gah) VALUES
('adaf**5013**dad344'),
('23**aab**yyyy'),
('zzz**402dha**vuuuda'),
('no**matches**here**lalala'),
('5013**aab**402dha'),
('402dha**aab**somethingelse**5013'),
('402dha**aab**5013');
데모 :
regress=> SELECT gah FROM test
WHERE regexp_split_to_array(gah, '\*\*') && ARRAY['5013', 'aab', '402dha'];
gah
----------------------------------
adaf**5013**dad344
23**aab**yyyy
zzz**402dha**vuuuda
5013**aab**402dha
402dha**aab**somethingelse**5013
402dha**aab**5013
(6 rows)
regress=> SELECT gah FROM test
WHERE regexp_split_to_array(gah, '\*\*') @> ARRAY['5013', 'aab', '402dha'];
gah
----------------------------------
5013**aab**402dha
402dha**aab**somethingelse**5013
402dha**aab**5013
(3 rows)
놀랍게도, 당신이 실제로 표현 인덱스의 PostgreSQL의 지원을 사용하여이 쿼리를 도움이됩니다 인덱스를 만들 수 있습니다. 물론, 당신이 그것을 의미하지 않는다 할 수있다해서 그것이 좋은 생각 :
regress=> CREATE INDEX test_glah_resplit_gin ON test
USING GIN((regexp_split_to_array(gah, '\*\*')));
CREATE INDEX
regress=> -- Only for testing purposes, don't use in production:
regress=> SET enable_seqscan = off;
SET
regress=> explain SELECT gah FROM test WHERE regexp_split_to_array(gah, '\*\*') @> ARRAY['5013', 'aab', '402dha'];
QUERY PLAN
-----------------------------------------------------------------------------------------------
Bitmap Heap Scan on test (cost=16.00..20.02 rows=1 width=32)
Recheck Cond: (regexp_split_to_array(gah, '\*\*'::text) @> '{5013,aab,402dha}'::text[])
-> Bitmap Index Scan on test_glah_resplit_gin (cost=0.00..16.00 rows=1 width=0)
Index Cond: (regexp_split_to_array(gah, '\*\*'::text) @> '{5013,aab,402dha}'::text[])
(4 rows)
regress=> explain SELECT gah FROM test WHERE regexp_split_to_array(gah, '\*\*') && ARRAY['5013', 'aab', '402dha'];
QUERY PLAN
-----------------------------------------------------------------------------------------------
Bitmap Heap Scan on test (cost=16.00..20.02 rows=1 width=32)
Recheck Cond: (regexp_split_to_array(gah, '\*\*'::text) && '{5013,aab,402dha}'::text[])
-> Bitmap Index Scan on test_glah_resplit_gin (cost=0.00..16.00 rows=1 width=0)
Index Cond: (regexp_split_to_array(gah, '\*\*'::text) && '{5013,aab,402dha}'::text[])
(4 rows)
GIN 인덱스를 업데이트 할 수 비싸다, 그래서 당신은이 방법을 사용하는 경우는 insert
/update
에 상당한 성능 가격을 지불 .그것은 일반적인 배열에서도 마찬가지입니다. regexp_split_to_table
을 사용하여 즉시 작성하면 조금 더 나빠질 수 있습니다. GIN tips 및 the intro to GIN indexes을 참조하십시오.
예를 들어, INSERT INTO test(gah) SELECT 'aaaaabbbbb'||(x::text) FROM generate_series(1,1000000) x;
을 사용하여 테스트 테이블에 백만 행을 삽입하려면 GIN 인덱스가있는 위치에서 22 초가 걸렸고, 떨어지면 1.6 초가 걸렸습니다. 그것은 값의 균일 성 때문에 특히 나쁜 경우 일 수 있습니다.
4. 하나의 열에 여러 값을 저장하지 않도록 데이터 모델을 다시 설계하십시오. –
'A'는 해당 표현식에 나타나지 않습니다. "당신이 썼을 때 **"매 ** "가 아닌, 한 열의 행의 어떤 부분에도 ** 요소가 ** 포함되어 있다면? –
@ user1751221 질문 할 때 설명을 요청하는 댓글에 * 답장하십시오. http://meta.stackexchange.com/questions/19756/how-do-comments-work –