이 질문은 "저의 숙제를하는 것처럼"느껴지 긴하지만,이 쿼리가 많은 행이있는 테이블에 대해 신속하게 실행되도록 노력하고 있습니다. Here's a SQLFiddle (다소 차이가 있음) 스키마를 보여줍니다.수억 개의 행을 가진 테이블에 대한 쿼리를 최적화하십시오.
나는 모든 필수 열을 보여줄 것이지만별로 성공하지 못했던 것을 얻기 위해 색인을 가지고 놀았습니다.
CREATE TABLE `AuditEvent` (
`auditEventId` bigint(20) NOT NULL AUTO_INCREMENT,
`eventTime` datetime NOT NULL,
`target1Id` int(11) DEFAULT NULL,
`target1Name` varchar(100) DEFAULT NULL,
`target2Id` int(11) DEFAULT NULL,
`target2Name` varchar(100) DEFAULT NULL,
`clientId` int(11) NOT NULL DEFAULT '1',
`type` int(11) not null,
PRIMARY KEY (`auditEventId`),
KEY `Transactions` (`clientId`,`eventTime`,`target1Id`,`type`),
KEY `TransactionsJoin` (`auditEventId`, `clientId`,`eventTime`,`target1Id`,`type`)
)
을 그리고 (버전)을 select
: 여기에 create
의
select ae.target1Id, ae.type, count(*)
from AuditEvent ae
where ae.clientId=4
and (ae.eventTime between '2011-09-01 03:00:00' and '2012-09-30 23:57:00')
group by ae.target1Id, ae.type;
나는뿐만 아니라 '사용 일시적인'과 '사용 filesort'와 끝까지. count(*)
을 삭제하고 대신 select distinct
을 사용하여 '파일 사용'을 발생시키지 않았습니다. 카운트를 얻기 위해 join
으로 돌아 가면 가능합니다.
원본으로 감사 레코드가 생성되었을 때와 같이 대상의 target1Name 및 target2Name을 추적하도록 결정되었습니다. 그 이름도 필요합니다 (가장 최근에 할 것입니다).
현재 위의 쿼리는 target1Name 및 target2Name 열이 누락되어 약 2400 만 개의 레코드에서 약 5 초 만에 실행됩니다. 우리의 목표는 수억 수천만에 달합니다. 쿼리를 계속 실행하고 싶습니다. (1-2 분 내에 유지하기를 원하지만, 우리는 그것을 훨씬 좋아야합니다.)하지만 두려움은 한 번입니다. 우리는 더 많은 양의 데이터를 쳤지 만 추가 행을 시뮬레이션하기 위해 노력하고 있습니다.
추가 입력란을 가져 오는 가장 좋은 전략은 확실하지 않습니다. select
에 열을 직접 추가하면 쿼리에서 '인덱스 사용'이 손실됩니다. 나는 테이블에 join
을 시도했는데, 이것은 'Using index'를 유지하지만 20 초 정도 걸린다.
eventTime 열을 datetime이 아닌 int로 변경하려고했으나 인덱스 사용이나 시간에 영향을 미치지 않았습니다.
당신이 아마 알고있는 것처럼
무엇 현재 쿼리 타이밍이고 당신이 아래 이해한다 : 당신이 질문을하면
는 바로이 다음 시도 (당신은 충분히 빨리 생각하는) 쿼리에 두 필드를 추가하는 방법을 그냥 "빨리"? – feeela
죄송합니다. 해당 세부 정보를 추가했습니다. –
clientId 및 eventTime에 인덱스가 있습니까? 또한 eventTime 인덱스를 사용 중이며 전체 테이블 스캔을 수행하지 않는 오브젝트가 있는지 확인하십시오. –