2010-08-14 6 views
2

MySQL에서 실행하는 데 약 15-20 초가 걸리는 쿼리를 최적화하려고했습니다. 내 데이터 테이블에는 약 10 백만 개의 행이 있으며 쿼리는 144 개의 "실행"필드와 35 개의 "이름"필드와 일치하는 68,000 개의 레코드를 반환하려고합니다. 쿼리는 두 개의 절을 사용하기 때문에 내 인덱스는별로 도움이되지 않습니다.2 개의 "in"절을 사용하여 쿼리 최적화

select * from data d where 
d.data_type='Result' and 
(d.run in ('8a7aee1f2a6232b1012a624da9201b92', '8a7aee1f2a6232b1012a625432a314ef' , 

... [144 runs] 

)) and (d.name like 'itema[%]' or d.name like 'itemb[%]') 

여기

CREATE TABLE `data` (
    `data_type` varchar(31) NOT NULL, 
    `id` char(32) NOT NULL, 
    `entry_time` datetime default NULL, 
    `name` varchar(255) NOT NULL, 
    `step` int(11) default NULL, 
    `value` double NOT NULL, 
    `run` char(32) NOT NULL, 
    PRIMARY KEY (`id`), 
    KEY `FK2EEFAA8ECCC6F3` (`run`), 
    KEY `data2` (`run`,`step`), 
    KEY `data3` (`data_type`,`name(10)`,`run`), 
    CONSTRAINT `FK2EEFAA8ECCC6F3` FOREIGN KEY (`run`) REFERENCES `run_archive` (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

키 데이터 3를 사용하는 나에게 질의를 알려줍니다 설명 테이블 정의를 다음과 같습니다

다음은 쿼리입니다.

id  select_type  table type possible_keys key  key_len ref rows Extra 
1  SIMPLE d range FK2EEFAA8ECCC6F3,data2,data3 data3 223  NULL 113271 Using where 

144 개의 쿼리 (각 실행마다 하나씩)를 실행하는 데 사용되었습니다. 하나의 쿼리를 수행하는 데 약 두 배나 빠르지 만 여전히 느립니다.

최적화를위한 제안? 내가 가진 아이디어는 다음과 같습니다

  • 은 (는 실행 제거하기 쉬운,하지만 이름에 대한
    열심히 것
    이 최대

  • 비정규 데이터 속도 마법의 인덱스를 찾기)

  • 분할 최대 다른 테이블 간의 데이터 (내 자바/최대 절전 모드 접근 할 하드)

아니면 여기서는 불가능한 질문을하고 있습니까?

편집 : 가장 큰 문제는 innodb_buffer_pool의 크기를 늘리는 것이 었습니다. 이 작업을 수행 한 후 약 1 초 30 초로 쿼리가 다운되었습니다. 필자는 "대답"으로 약간 개선 된 수정으로 표시했습니다.

+0

where 절의 개별 제한 사항의 선택도는 무엇입니까? 즉 '결과'데이터 유형을 가진 행 수, 일치하는 실행이있는 행 수 및 일치하는 이름을 가진 행의 수는 테이블에 있습니까? – meriton

+0

편집 : data3 키가 잘못되었습니다. (나는 handedit). 첫 번째 필드는 data_type입니다. –

답변

0

run의 상태가 얼마나 선택에 따라, 인덱스

data_type, run, name(10) 
에게 제공하기 위해 더 좋을 수도

접두사 초기 인덱스의 일치에 사용되는 열을 제공의 문제점은에서 일치하는 행을 산란이다 인덱스에서 디스크의 더 큰 부분을 읽어야합니다.

또한 실행 ID에 더 작은 데이터 유형을 사용하면 색인 크기가 줄어들고 비교 속도가 빨라집니다. 이는 지속적인 요인 개선이지만 상관없이 가치가있을 수 있습니다.

+0

도움이됩니다. 내 노트북에서 실행되는이 색인의 경우 78 초이고 다른 색인의 경우 135입니다. –

1

result 개의 레코드를 data 테이블에서 분리 해보십시오. 나는 당신의 result이 어떤 비율인지 알지 못했지만 Prod 데이터베이스의 Dev 복사본에서 벤치 마크 할 가치가 있습니다.

run 값을 FK 할 수 있습니까? 재사용 할 수 있다면 (?) 아마도 Run 테이블을 만드시겠습니까? 제 생각에 144 문자열 일치, 심지어 색인을 생성, 그들은 int 또는 smallint 있다면 느립니다. 이 제안이나 다른 제안을 벤치마킹하는 것은 분명히 이론을 증명할 것입니다.

name 속성에 like 절을 포함하지 않을 경우 쿼리 계획의 차이점은 어떻게 생깁니 까?

+0

data3 키가 잘못되었습니다. (나는 handedit). 첫 번째 필드는 data_type입니다. –

+0

데이터의 약 80 %가 "결과"data_type입니다. 또한, 나는 Run 테이블을 가지고있다. "run"필드는 실행 테이블에 외부 키가 있지만 char (32) id를 통해 나온다. 조인을하는 것은 거의 동일한 성능 인 것으로 보입니다. 데이터의 이식성을 위해 정수 대신 char (32)를 사용합니다 (서버간에 이동해야하는 경우). –

+0

"like"라는 이름을 36 가지 가능성을 설명하는 in 절로 대체하면 거의 동일한 성능을 갖습니다. –