我有一个使用PHP / Laravel构建的Web服务。正在形成查询的其中一个表包含超过2300万行。
其中一个查询,大部分时间执行正常。但是,有时当我通过MySQLWorkbench查看客户端连接时,我发现有一组查询似乎被卡住了。发生这种情况时,同一查询的未来执行速度会降低,并且数据库上的CPU使用率会增加。
我似乎无法手动复制该问题,也无法通过使用消耗API数据的移动应用程序来复制问题,所有查询都在合理的时间内成功完成。
当我看到MySQLWorkbench时,这就是我所看到的;
正在执行的查询是;
SELECT af.*, a.name, a.picture AS profile_picture
FROM artist_feeds AS af
STRAIGHT_JOIN user_artists AS ua ON ua.artist_id = af.artist_id
STRAIGHT_JOIN artists AS a ON a.id = af.artist_id
LEFT OUTER JOIN user_artist_disabled_networks AS uadn
ON uadn.user_id = ua.user_id AND uadn.socialnetwork_id = af.socialnetwork_id
WHERE af.feed_date >= '2010-10-29'
AND uadn.user_id IS NULL
AND ua.user_id = 498
ORDER BY af.feed_date DESC
LIMIT 0, 20
EXPLAIN显示以下内容;
SHOW CREATE TABLE的响应是;
CREATE TABLE `artist_feeds` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`feed_id` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`feed_date` datetime DEFAULT NULL,
`message` text COLLATE utf8mb4_unicode_ci,
`hash` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`type` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`source` mediumtext COLLATE utf8mb4_unicode_ci,
`picture` mediumtext COLLATE utf8mb4_unicode_ci,
`link` mediumtext COLLATE utf8mb4_unicode_ci,
`artist_id` int(11) DEFAULT '0',
`socialnetwork_id` int(11) DEFAULT '0',
`direct_link` mediumtext COLLATE utf8mb4_unicode_ci,
`is_master_feed` tinyint(4) DEFAULT '0',
`active` tinyint(4) DEFAULT '0',
`created_at` datetime DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`rss_feed_id` int(11) DEFAULT '0',
PRIMARY KEY (`id`),
KEY `artist_id` (`artist_id`),
KEY `socialnetwork_id` (`socialnetwork_id`),
KEY `feedidnetwork` (`feed_id`(191),`socialnetwork_id`),
KEY `feeddatenetworkid` (`feed_date`,`socialnetwork_id`),
KEY `feeddatenetworkidartistid` (`artist_id`,`socialnetwork_id`,`feed_date`),
KEY `type` (`type`)
) ENGINE=InnoDB AUTO_INCREMENT=26991713 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
有没有人有任何想法为什么这个查询偶尔会被“卡住”?我假设它“卡住”做某事,因为一旦你有5个这样的查询“卡住”,数据库的响应时间就会减慢,CPU使用率也会增加。
答案 0 :(得分:0)
您为什么使用STRAIGHT JOIN
?让优化器完成它的工作。
我会写这样的查询:
SELECT af.*, a.name, a.picture AS profile_picture
FROM user_artists ua JOIN
artist_feeds af
ON ua.artist_id = af.artist_id JOIN
artists a
ON a.id = af.artist_id
user_artist_disabled_networks uadn LEFT JOIN
ON uadn.user_id = ua.user_id AND
uadn.socialnetwork_id = af.socialnetwork_id
WHERE af.feed_date >= '2010-10-29' AND
uadn.user_id IS NULL
ua.user_id = 498
ORDER BY af.feed_date DESC
LIMIT 0, 20
我的第一个倾向是加入user_artists(user_id, artist_id)
,user_feeds(artist_id, feed_date)
和user_artist_disabled_networks(user_id, socialnetwork_id)
。