MySQL innoDB:查询执行时间过长
Posted
技术标签:
【中文标题】MySQL innoDB:查询执行时间过长【英文标题】:MySQL innoDB: Long time of query execution 【发布时间】:2013-05-10 11:17:20 【问题描述】:我在运行此 SQL 时遇到问题:
我认为是index problem
,但我不知道,因为我不制作这个数据库,我只是一个简单的程序员。
问题是,那个表有64260条记录,所以查询在执行的时候很疯狂,我不得不停止mysql重新运行,因为计算机被冻结了。
谢谢。
编辑:表架构
CREATE TABLE IF NOT EXISTS `value_magnitudes` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`value` float DEFAULT NULL,
`magnitude_id` int(11) DEFAULT NULL,
`sdi_belongs_id` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`reading_date` datetime DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1118402 ;
查询
select * from value_magnitudes
where id in
(
SELECT min(id)
FROM value_magnitudes
WHERE magnitude_id = 234
and date(reading_date) >= '2013-04-01'
group by date(reading_date)
)
EDIT2
【问题讨论】:
那么,您的问题是什么? 我需要改进该表,以便快速进行该查询,我不知道如何索引或索引什么,因为图片显示很多 null 并且它们不好。跨度> 【参考方案1】:首先,在(magnitude_id, reading_date)
上添加一个索引:
ALTER TABLE
ADD INDEX magnitude_id__reading_date__IX -- just a name for the index
(magnitude_id, reading_date) ;
然后试试这个变化:
SELECT vm.*
FROM value_magnitudes AS vm
JOIN
( SELECT MIN(id) AS id
FROM value_magnitudes
WHERE magnitude_id = 234
AND reading_date >= '2013-04-01' -- changed so index is used
GROUP BY DATE(reading_date)
) AS vi
ON vi.id = vm.id ;
GROUP BY DATE(reading_date)
仍需要将该函数应用于所有选定的(通过索引)行并且无法改进,除非您遵循@jurgen 的建议并将列拆分为date
和time
列。
【讨论】:
那么,它有帮助吗?现在执行时间如何? 你编辑了它,但是第一版是在 0,005 秒内执行的,所以很神奇@ypercube 不知道为什么它这么快,因为我没有索引来尝试是否是问题,而且它运行得很好 =) 我的编辑没有改变代码。我只添加了 cmets 和最后一段。很高兴听到它现在运行得很快。【参考方案2】:由于您想获得每天的结果,您需要使用函数date()
从日期时间列中提取日期。这使得索引毫无用处。
您可以将reading_date
列拆分为reading_date
和reading_time
。然后您可以在没有函数的情况下运行查询,并且索引将起作用。
此外,您可以将查询更改为join
select *
from value_magnitudes v
inner join
(
SELECT min(id) as id
FROM value_magnitudes
WHERE magnitude_id = 234
and reading_date >= '2013-04-01'
group by reading_date
) x on x.id = v.id
【讨论】:
【参考方案3】:对于初学者,我会将您的查询更改为:
select * from value_magnitudes where id = (
select min(id) from value_magnitudes
where magnitude_id = 234
and DATE(reading_date) >= '2013-04-01'
)
当子查询只返回一条记录时,您不需要使用 IN 子句。
然后,我会确保您有一个关于magnitude_id 和 reading_date 的索引(可能是一个两字段索引),因为这就是您在子查询中查询的内容。如果没有该索引,您每次都在扫描表。
如果可能的话,将magnitude_id 和reading_date 更改为非空值。空值和索引不是很合适。
【讨论】:
查询中有group by
。所以子查询中没有一条记录
我需要您的帮助添加索引 =)
查看@ypercube 的答案,因为他提供了用于添加索引的表更改以上是关于MySQL innoDB:查询执行时间过长的主要内容,如果未能解决你的问题,请参考以下文章