2013-08-20 2 views
1

나는 9 백만 레코드가있는 InnoDB 테이블을 가지고있다. UNION DISTINCT가 9 백만 건의 레코드보다 빠릅니다.

내가이

SELECT 
    my_primary_key 
FROM 
    my_table 
WHERE 
    col1 = 1 AND 
    col2 = 2 AND 
    (col3 = 'aaa' OR col4 = 'bbb' OR col5 = 'ccc') 

내 테이블 구조 같은 쿼리를 위해 사용 : 내 친구의 제안을 바탕으로

CREATE TABLE IF NOT EXISTS `my_table` (
    `my_primary_key` bigint(20) unsigned NOT NULL AUTO_INCREMENT, 
    `col1` tinyint(1) unsigned NOT NULL DEFAULT '0', 
    `col2` tinyint(1) unsigned NOT NULL DEFAULT '0', 
    `col3` varchar(255) NOT NULL, 
    `col4` varchar(255) NOT NULL, 
    `col5` varchar(255) NOT NULL, 
    PRIMARY KEY (`my_primary_key`), 
    KEY `col1` (`col1`), 
    KEY `col2` (`col2`), 
    KEY `col3` (`col3`), 
    KEY `col4` (`col4`), 
    KEY `col5` (`col5`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 

, 내가로 변경하려고

SELECT my_primary_key FROM my_table WHERE col1 = 1 AND col2 = 2 AND col3 = 'aaa' 
UNION DISTINCT 
SELECT my_primary_key FROM my_table WHERE col1 = 1 AND col2 = 2 AND col4 = 'bbb' 
UNION DISTINCT 
SELECT my_primary_key FROM my_table WHERE col1 = 1 AND col2 = 2 AND col5 = 'ccc' 

그러나 내가 실행중인 쿼리를 보려고하면 "시간"이 여전히 꽤 높다는 것을 알 수 있습니다 (8-20 초 사이)

SHOW FULL PROCESSLIST 

UNION DISTINCT를 사용하여 올바른 경로에 있습니까? 아니면 내 쿼리를 실행하는 다른 빠른 방법이 있습니까?

감사합니다.

+0

색인 선택성이 무엇인지 모르는 경우가 많습니다. 일반적으로 낮은 선택성 때문에 TINYINT 열을 인덱싱하지 않습니다. 그러나 컬럼 col1과 col2가 더 높은 선택성을 가지면 컨버전 인덱스를 만들어 전달 된 테이블과 JOIN을 사용하여 불일치를 필터링 할 수 있습니다. –

답변

0

나는 일반적으로 or이 가장 빠르다고 생각합니다. 그러나 전체 테이블 스캔이 필요합니다. 검색 대신 사용할 수있는 (col1, col2, col3, col4, col5, my_primary_key)의 복합 색인을 사용해 볼 수 있습니다.

union distinct은 각 절이 인덱스를 사용할 수 있고 반환되는 행이 비교적 적 으면 빠를 것입니다. 따라서 다음 색인을 사용하여 실행 해보십시오.

mytable(col1, col2, col3, my_primary_key) 
mytable(col1, col2, col4, my_primary_key) 
mytable(col1, col2, col5, my_primary_key) 

최적화 과정에서 전체 테이블 검색을 피하려고합니다. union distinct은 올바른 색인으로이를 달성 할 수 있습니다.

+0

설명해 주셔서 감사합니다. 그러나 내가 몇 가지 인덱스를 추가하려는 경우 다른 문제에 직면하고있다, 내가 마지막으로 시도했을 때, (나는 많은 데이터를 가지고 있기 때문에) 아마도 인덱스를 추가하는 데 오랜 시간이 걸렸다. 테이블 구조를 빠르게 변경하는 방법에 대한 제안이 있습니까? – Xrvel

+0

9 백만 레코드가있는 InnoDB 테이블의 Alter 테이블은 오래 걸리지 만, InnoDB 엔진 버전에서 어떤 인덱스를 바꿀 것인지를 결정합니다. 새로운 InnoDB 엔진 버전은 빠른 인덱스 생성이라는 기능을 지원합니다. 그 좋은 기능을 기본적으로 지원하는 버전이어야합니다. –

관련 문제