2012-04-13 6 views
0

아마존 RDS에서 MySQL 데이터베이스가있는 애플리케이션으로 작업하고 있습니다. 질문의 표는 같은 설정 :MySQL 테이블 인덱스 최적화

CREATE TABLE `log` (
    `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, 
    `timestamp` datetime NOT NULL, 
    `username` varchar(45) NOT NULL, 
    .. snip some varchar and int fields .. 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 

이 시스템은 잠시 동안 베타 왔으며 이미 데이터 세트는 매우 거대하고 쿼리 오히려 느린하기 시작했다.

SELECT COUNT(*) FROM log --> 16307224 (takes 105 seconds to complete) 

이 표는 거의만을 의미, 일반적으로 완료하는 데 약 100-180 초를 가지고 1000 6000 행 사이 뭔가를 줄 것이다이

SELECT timestamp, username, [a few more] FROM log 
WHERE timestamp BETWEEN '2012-03-30 08:00:00' AND '2012-03-30 16:00:00' 
AND username='XX' 

같은 쿼리 떨어져 하나 개의 보고서를 구축하는 데 사용됩니다 웹 응용 프로그램은 종종 시간이 초과되어 빈 보고서를 남깁니다 (시간 초과를 조사 할 것이지만이 질문은 근본 원인에 대한 것입니다).

저는 데이터베이스에는별로 좋지 않지만, 제 생각 엔 여기에서 저를 죽이는 것입니다. 내가 생각하기에 아마도 어떻게 든 타임 스탬프를 인덱스로 사용해야 할 것입니다. 사용자 이름과 함께하는 시간 기록은 고유성을 제공해야합니다 (ID 필드를 사용하지 않습니다).

최적화에 대한 제안 사항이있는 사람이 있다면 모든 귀가 있습니다.

UPDATE :

표는 이제 SELECT 문 다음

CREATE TABLE `log` (
    `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, 
    `timestamp` datetime NOT NULL, 
    `username` varchar(45) NOT NULL, 
    .. snip .. 
    `task_id` int(10) unsigned DEFAULT NULL, 
    PRIMARY KEY (`id`), 
    KEY `index_un_ts` (`timestamp`,`username`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 

EXPLAIN로 변경되어있을 것 타임 스탬프 열 및 사용자 ID에 다음

id => 1 
select_type => SIMPLE 
table => log 
type => range 
possible_keys => index_un_ts 
key => index_un_ts 
key_len => 55 
ref => 
rows => 52258 
Extra => Using where; Using index 
+0

MyISAM으로 전환 할 수 있습니다. 예를 들어 매일 cron으로 데이터를 집계하고 별도의보고 표에 저장하십시오. –

답변

1

솟아 인덱스를 반환 도움이됩니다. EXPLAIN 문 출력을 읽을 수 있어야합니다.

는 다음의 MySQL로 이동하여 수행

EXPLAIN SELECT timestamp, username, [a few more] FROM log 
WHERE timestamp BETWEEN '2012-03-30 08:00:00' AND '2012-03-30 16:00:00' 
AND username='XX' 

이 쇼 당신에게 MySQL이 쿼리를 실행하는 데 사용하는 계획을. 키라는 열이있을 것입니다. 이것은 쿼리에서 MySQL이 사용하고있는 인덱스를 나타냅니다. MySQL이 where 절에 대한 모든 행과 일치하는 맨 위에서 아래로 테이블을 스캔한다는 것을 의미합니다. 이제 timestamp 및 userid 열에 대한 색인을 작성하십시오. EXPLAIN 문을 다시 실행하십시오. 키 열에서 작성한 색인이 표시되어야합니다.

MySQL이 색인을 사용하면 쿼리가 상당히 빨라야합니다. 색인 초과를 기억하지 마십시오. 인덱스를 사용하면 삽입, 업데이트 및 삭제 속도가 느려집니다. 테이블에 새 행을 삽입 할 때 테이블에 세 개의 인덱스가 있으면 새 행은 3 개의 다른 인덱스에 3 개의 값을 써야합니다. 그래서 그것은 양날의 칼입니다.

+0

아, 그냥 인덱스 작성 명령문이 잠시 실행되므로 그냥 앉아 있으면 당황하지 마십시오. 그것은 entires 테이블을 스캔하여 값을 얻은 다음 새로운 인덱스 구조에 삽입해야합니다. 색인은 디스크에 저장된 B-tree 또는 R-tree이며 테이블과 동기화 상태를 유지합니다. – Namphibian

+0

openark 키트로 테이블을 변경하십시오. –

+1

설명이 ALL로 돌아옵니다. 타임 스탬프 용과 사용자 이름 용 중 하나 또는 둘의 복합 인덱스 두 개를 만드는 것이 좋습니다. – danneth