MySQL (MAMP 내에서 실행)에 큰 테이블이 있고 2800 만 개의 행과 3.1GB의 크기가 있습니다. 다음은 그 구조 여기매우 느린 선택이있는 큰 MySQL 테이블
CREATE TABLE `termusage` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`termid` bigint(20) DEFAULT NULL,
`date` datetime DEFAULT NULL,
`dest` varchar(255) DEFAULT NULL,
`cost_type` tinyint(4) DEFAULT NULL,
`cost` decimal(10,3) DEFAULT NULL,
`gprsup` bigint(20) DEFAULT NULL,
`gprsdown` bigint(20) DEFAULT NULL,
`duration` time DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `termid_idx` (`termid`),
KEY `date_idx` (`date`),
KEY `cost_type_idx` (`cost_type`),
CONSTRAINT `termusage_cost_type_cost_type_cost_code` FOREIGN KEY (`cost_type`) REFERENCES `cost_type` (`cost_code`),
CONSTRAINT `termusage_termid_terminal_id` FOREIGN KEY (`termid`) REFERENCES `terminal` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=28680315 DEFAULT CHARSET=latin1
은 테이블 표시 상태의 출력입니다 :
Name,Engine,Version,Row_format,Rows,Avg_row_length,Data_length,Max_data_length,Index_length,Data_free,Auto_increment,Create_time,Update_time,Check_time,Collation,Checksum,Create_options,Comment
'termusage', 'InnoDB', '10', 'Compact', '29656469', '87', '2605711360', '0', '2156920832', '545259520', '28680315', '2011-08-16 15:16:08', NULL, NULL, 'latin1_swedish_ci', NULL, '', ''
임 다음 select 문을 실행하려고 :
select u.id from termusage u
where u.date between '2010-11-01' and '2010-12-01'
이 돌아갑니다 35 분 소요 결과 (약 1400 만 행) - 이것은 MySQL Worksbench를 사용하고 있습니다.
나는 다음과 같은 MySQL의 구성 설정이 있습니다
Variable_name Value
bulk_insert_buffer_size 8388608
innodb_buffer_pool_instances 1
innodb_buffer_pool_size 3221225472
innodb_change_buffering all
innodb_log_buffer_size 8388608
join_buffer_size 131072
key_buffer_size 8388608
myisam_sort_buffer_size 8388608
net_buffer_length 16384
preload_buffer_size 32768
read_buffer_size 131072
read_rnd_buffer_size 262144
sort_buffer_size 2097152
sql_buffer_result OFF
는 결국 더 큰 쿼리를 실행하려고 메신저 - 테이블 및 그룹 일부 데이터의 몇 가지를 결합, 모든 변수에 따라 - 고객 ID -
을select c.id,u.termid,u.cost_type,count(*) as count,sum(u.cost) as cost,(sum(u.gprsup) + sum(u.gprsdown)) as gprsuse,sum(time_to_sec(u.duration)) as duration
from customer c
inner join terminal t
on (c.id = t.customer)
inner join termusage u
on (t.id = u.termid)
where c.id = 1 and u.date between '2011-03-01' and '2011-04-01' group by c.id,u.termid,u.cost_type
이것은 최대 8 개의 행을 반환합니다 (8 개의 별도 cost_types가 있기 때문에). 그러나이 쿼리는 termusage 테이블에 계산할 행이 100 만 개가 넘지 않는 곳에 OK로 실행됩니다. termusage 테이블의 행 수가 큽니다. 선택 시간을 줄일 수 있습니까?
데이터는 LOAD DATA 방법을 사용하여 CSV 파일에서 월 단위로 한 번씩 추가되므로 삽입을 위해 너무 조정할 필요가 없습니다.
편집 : 쇼 메인 쿼리에 대해 설명합니다
id,select_type,table,type,possible_keys,key,key_len,ref,rows,Extra
1,SIMPLE,c,const,PRIMARY,PRIMARY,8,const,1,"Using index; Using temporary; Using filesort"
1,SIMPLE,u,ALL,"termid_idx,date_idx",NULL,NULL,NULL,29656469,"Using where"
1,SIMPLE,t,eq_ref,"PRIMARY,customer_idx",PRIMARY,8,wlnew.u.termid,1,"Using where"
show from query. –