繁体   English   中英

非常慢的简单mysql查询

[英]Very slow simple mysql query

我有一个非常慢的mysql查询,如下所示:

SELECT function,  CONVERT_TZ(`time`, '+01:00','+01:00') 
FROM `function_logger` 
WHERE unit_id=3067785 
  and part_id=3 and channel=0  
  and `time` > NOW()-INTERVAL 1 DAY 
order by time;

用于以下表格结构

CREATE TABLE IF NOT EXISTS `function_logger` (
  `id` int(11) NOT NULL,
  `unit_id` int(11) NOT NULL,
  `part_id` tinyint(4) NOT NULL DEFAULT '0',
  `channel` tinyint(4) NOT NULL DEFAULT '0',
  `function` tinyint(11) NOT NULL,
  `time` datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

ALTER TABLE `function_logger`
  ADD PRIMARY KEY (`id`),
  ADD KEY `unit_id` (`unit_id`);

该表包含约8000万条记录,但运行大约需要一分钟。 一旦缓存就可以了。

unit_id包含大约3000个不同的随机数,part_id最多10个,通道最多3个。

反正有加速的吗?

分区会有所帮助吗?

假设unit_id分布均匀,然后在80m条记录中选择特定的一项(从3000条中选择),则您有超过25k条记录需要检查。

由于您没有进一步的索引帮助,MySQL当前必须检索并检查这25k条记录中的每条记录,以确定它们是否与其余过滤条件匹配。

添加复合索引(即在多个列上定义的复合索引)将在这里为您提供帮助-MySQL可以进一步减少它需要检查的记录。 但是,由于基数很低, part_idchannel可能无济于事。 目前尚不清楚,从可能存在什么样的基数的time ,但是这可能是一个很好的起点:

CREATE INDEX unit_time ON function_logger (unit_id, time)

您也可以添加其他过滤器列(尽管要注意time应该倒数,因为您正在搜索一个范围)—但是,索引中的列越多,写入表的速度就越慢(并且越大索引文件和内存占用量)。

最快的读取性能将通过覆盖指数获得:

CREATE INDEX covering ON function_logger (
  unit_id, part_id, channel, time, function
)

尝试/测试不同的索引时,请执行解释并比较结果。 USE INDEX将帮助您测试不同的索引,并在select语句中添加该提示(请不要使用qc)。

set profiling = on;

select * from function_logger;
show profiles;
show profile for query N;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM