【发布时间】:2019-08-13 13:52:12
【问题描述】:
您好,我目前有一个查询需要 11(秒)才能运行。我有一个显示在网站上的报告,该网站运行 4 个不同的查询,这些查询是相似的,每个都需要 11(秒)才能运行。我真的不希望客户等待所有这些查询运行并显示数据。
我正在使用 4 个不同的 AJAX 请求来调用 API 以获取我需要的数据,这些请求都是同时启动的,但是查询一个接一个地运行。如果有办法让这些查询一次全部运行(并行),因此总加载时间只有 11(秒),这也可以解决我的问题,但我认为这是不可能的。
这是我正在运行的查询:
SELECT device_uuid,
day_epoch,
is_repeat
FROM tracking_daily_stats_zone_unique_device_uuids_per_hour
WHERE day_epoch >= 1552435200
AND day_epoch < 1553040000
AND venue_id = 46
AND zone_id IN (102,105,108,110,111,113,116,117,118,121,287)
无论如何我都想不出加快这个查询的速度,下面是表索引的图片和这个查询的解释语句。
我认为上面的查询在 where 条件下使用了相关索引。
如果您有什么可以加快查询速度的方法,请告诉我,我已经研究了 3 天,但似乎无法找出问题所在。将查询时间缩短到最大 5(秒)会很棒。如果我对 AJAX 问题有误,请告诉我,因为这也可以解决我的问题。
" 编辑 "
我遇到了一些很奇怪的东西,可能是导致问题的原因。当我将 day_epoch 范围更改为较小的(第 5 - 9 日)返回 130,000 行时,查询时间为 0.7(秒),但随后我在该范围(第 5 - 10 日)上再添加一天,它返回超过 150,000 行的查询时间是 13(秒)。我已经运行了不同范围的负载,并得出结论,如果返回的行数超过 150,000,这会对查询时间产生巨大影响。
表定义-
CREATE TABLE `tracking_daily_stats_zone_unique_device_uuids_per_hour` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`day_epoch` int(10) NOT NULL,
`day_of_week` tinyint(1) NOT NULL COMMENT 'day of week, monday = 1',
`hour` int(2) NOT NULL,
`venue_id` int(5) NOT NULL,
`zone_id` int(5) NOT NULL,
`device_uuid` binary(16) NOT NULL COMMENT 'binary representation of the device_uuid, unique for a single day',
`device_vendor_id` int(5) unsigned NOT NULL DEFAULT '0' COMMENT 'id of the device vendor',
`first_seen` int(10) unsigned NOT NULL DEFAULT '0',
`last_seen` int(10) unsigned NOT NULL DEFAULT '0',
`is_repeat` tinyint(1) NOT NULL COMMENT 'is the device a repeat for this day?',
`prev_last_seen` int(10) NOT NULL DEFAULT '0' COMMENT 'previous last seen ts',
PRIMARY KEY (`id`,`venue_id`) USING BTREE,
KEY `venue_id` (`venue_id`),
KEY `zone_id` (`zone_id`),
KEY `day_of_week` (`day_of_week`),
KEY `day_epoch` (`day_epoch`),
KEY `hour` (`hour`),
KEY `device_uuid` (`device_uuid`),
KEY `is_repeat` (`is_repeat`),
KEY `device_vendor_id` (`device_vendor_id`)
) ENGINE=InnoDB AUTO_INCREMENT=450967720 DEFAULT CHARSET=utf8
/*!50100 PARTITION BY HASH (venue_id)
PARTITIONS 100 */
【问题讨论】:
-
我相信 MySQL 通常一次只能利用一个索引,因此单独索引字段可能不是最佳选择;我建议尝试在
(venue_id, day_epoch)或(venue_id, zone_id, day_epoch)上创建一个复合索引。 ...此外,在问题中包括您的表的 CREATE 永远不会受到伤害。 -
GROUP BY通常用于聚合,您是否希望在未分组的字段中选择半随机值? -
@Uueerdo 上面的查询不是整个查询我有一个需要
GROUP BY的外部选择,但我没有费心展示,因为这不是问题,内部查询(如图所示)正在减慢速度。我将尝试创建该复合索引。 -
如果 GROUP BY 用于外部查询,则不需要包含在您发布的内容中;并且原始查询应该有一个
)将您发布的内容与 GROUP BY 之前的外部部分分开。 -
@Uueerdo 包含
GROUP BY的原因是因为这可能会减慢查询速度。我知道你不知道它为什么在那里,我现在已经解释过了。我认为问题是由于我所做的编辑。
标签: mysql performance query-optimization