gpt4 book ai didi

mysql - 选择非常慢的大型 MySQL 表

转载 作者:行者123 更新时间:2023-11-29 05:40:35 25 4
gpt4 key购买 nike

我在 MySQL 中有一个大表(在 MAMP 中运行),它有 2800 万行,大小为 3.1GB。这是它的结构

    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

这是 SHOW TABLE STATUS 的输出:

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 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 万)行来计算 - 但是当术语表中的行很大 - 如何减少选择时间。

每月使用 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"

最佳答案

看起来您在问两个问题 - 对吗?

第一个查询花费这么长时间的最可能原因是它受 IO 限制。将 1400 万条记录从磁盘传输到您的 MySQL 工作台需要很长时间。

您是否尝试过通过“解释”来输入第二个查询?是的,您只能返回 8 行 - 但 SUM 操作可能会对数百万条记录求和。

我假设“客户”和“终端”表已正确编入索引?当您加入 termusage 的主键时,这应该非常快......

关于mysql - 选择非常慢的大型 MySQL 表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7091229/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com