2014-02-21 2 views
3

내가 다음과 같이 큰 테이블이 여러 파일에서 게놈 위치를 포함 말해봐 :파생 테이블에서 인덱스가 지속됩니까?

CREATE TABLE chromosomal_positions (
    file_id INT, 
    chromosome_id INT, 
    position INT 
) 

내가 모든 중복에 대한 다른 모든 파일의 내용 (1 개) 파일의 내용을 비교합니다. 그래서 파생 된 테이블을 사용합니다. 나는 순서대로 FILE_ID, chromosome_id 위치에 복합 인덱스를 추가하는 경우

SELECT Count(*) 
FROM (SELECT * 
     FROM chromosomal_positions 
     WHERE variant_file_id = 1) AS file_1 
     JOIN (SELECT * 
      FROM chromosomal_positions 
      WHERE variant_file_id != 1) AS other_files 
     ON (file_1.chromosome_id = other_files.chromosome_id 
       AND file_1.position = other_files.position) 

이제, 파생 테이블은 인덱스를 사용 할 수 있습니까? (Postgres 사용)

+0

오, 내가 이것을 indicies로 편집하고 싶지만 미국인들이 나를 혼전시킬 것이라고 알고 있습니다! – Liath

+0

나는 당신이 정확하게 맞는지 모르겠다. http://forum.wordreference.com/showthread.php?t = 321709 –

+0

나는 네가 옳다고 생각한다. 나는 항상 GB/US 차이점으로 생각했다. 개인적인 취향이기 때문에 편집할만한 가치가 없다. 죄송합니다 나는 실제로 귀하의 질문에 대답 할 수 없다 - 나는 Postgres에 많은 경험이 없다. ( – Liath

답변

2

PostgreSQL이 하위 쿼리에서 인덱스를 "보존"하는 것은 아닙니다. 다시 말해서 기본 테이블에서 직접 작동하도록 쿼리를 단순화하고 재구성 할 수 있기 때문입니다.

이 경우 쿼리가 불필요하게 복잡합니다. 하위 쿼리를 완전히 제거하여 사소한 자체 조인을 만들 수 있습니다.

SELECT count(*) 
FROM chromosomal_positions file_1 
INNER JOIN chromosomal_positions other_files 
ON (file_1.chromosome_id = other_files.chromosome_id 
    AND file_1.position = other_files.position) 
WHERE file1.variant_file_id = 1 
AND other_files.variant_file_id != 1; 

따라서 (chromosome_id, position)의 색인은 여기에서 분명히 유용합니다.

explain analyze을 사용하여 인덱스 선택 및 사용법을 실험하여 쿼리 계획자가 실제로 무엇을하는지 확인할 수 있습니다.

                    QUERY PLAN                     
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
Aggregate (cost=78.01..78.02 rows=1 width=0) 
    -> Hash Join (cost=29.27..78.01 rows=1 width=0) 
     Hash Cond: ((chromosomal_positions_1.chromosome_id = chromosomal_positions.chromosome_id) AND (chromosomal_positions_1."position" = chromosomal_positions."position")) 
     -> Bitmap Heap Scan on chromosomal_positions chromosomal_positions_1 (cost=14.34..48.59 rows=1930 width=8) 
       Filter: (file_id <> 1) 
       -> Bitmap Index Scan on cp_f_c_p (cost=0.00..13.85 rows=1940 width=0) 
     -> Hash (cost=14.79..14.79 rows=10 width=8) 
       -> Bitmap Heap Scan on chromosomal_positions (cost=4.23..14.79 rows=10 width=8) 
        Recheck Cond: (file_id = 1) 
        -> Bitmap Index Scan on cp_f_c_p (cost=0.00..4.23 rows=10 width=0) 
          Index Cond: (file_id = 1) 
(11 rows) 

(view on explain.depesz.com)

가를 사용하면서 보여주는 : 나는

CREATE INDEX cp_f_c_p ON chromosomal_positions(file_id, chromosome_id , position); 

-- Planner would prefer seqscan because there's not really any data; 
-- force it to prefer other plans. 
SET enable_seqscan = off; 

EXPLAIN SELECT count(*) 
FROM (
    SELECT * 
    FROM chromosomal_positions 
    WHERE file_id = 1 
) AS file_1 
INNER JOIN (
    SELECT * 
    FROM chromosomal_positions 
    WHERE file_id != 1 
) AS other_files 
ON (file_1.chromosome_id = other_files.chromosome_id 
    AND file_1.position = other_files.position) 

하고 결과를 얻을 것 다음

: 예를 들어, 내가 원한다면 볼 수 인덱스는 실제로 첫 번째 열에 만 사용됩니다. 나머지는 사용하지 않으며 단지 file_id에 필터링됩니다. 따라서 다음의 색인은 유지 보수가 더 좋고 작고 저렴합니다.

CREATE INDEX cp_file_id ON chromosomal_positions(file_id); 

확실히이 색인을 만들면 Pg가 선호합니다. 따라서 제안자가 제안한 색인은 플래너가이 데이터 규모에서 사용할 가치가 없다고 생각하지 않는 한 유용하지 않은 것으로 보입니다. 더 많은 데이터가있는 완전히 다른 계획에서 사용하도록 선택할 수도 있습니다. 확실하게 실제 데이터를 테스트해야합니다. 반대로

내 제안 지수 :

CREATE INDEX cp_ci_p ON chromosomal_positions (chromosome_id, position); 

is used 적어도 빈 더미 데이터 세트, ID = 1 염색체 위치를 찾을 수있다. 그러나 플래너가 이보다 더 큰 데이터 세트에서 중첩 된 루프를 피할 것이라고 생각합니다. 그래서 다시 당신은 그것을 시험해보고을 봐야합니다.

(게시자가 하위 쿼리를 구체화해야 할 경우 구체화 된 하위 쿼리 인 '파생 테이블의 인덱스를 유지하지 않음') 특히 이는 구체화되는 WITH (CTE) 쿼리 용어와 관련이 있습니다.

+0

사실이지만, 나는 여전히 좋아할 것이다. 내 질문에 대한 답을 알고있다 –

+0

@wobbily_col rewriter는 원래의 쿼리를 위에서 쓴 것으로 바꿀 것이다. 그래서 "파생 된 테이블"은 말할 필요가 없다. 인덱스 사용 여부를 결정하려면,'EXPLAIN'을 사용해야한다. 위의 과정을 보여주었습니다. 편집을 참조하십시오. –

+0

불행히도 내 데이터 세트는 꽤 커서 점점 의미있는 벤치 마크는 영원히 계속되고 있습니다. –