我正在处理一个PHP Web服务,它需要在一个23万条记录的表上执行查询。我创建的查询似乎需要30多秒才能完成,并且从我可以告诉它是导致问题的查询部分的顺序,因为如果没有它,查询会快速响应。在23m行非常慢的表上的MySQL查询
这是查询;
SELECT artist_feeds.*, artists.name, artists.picture AS profile_picture
FROM artist_feeds
INNER JOIN user_artists ON user_artists.artist_id = artist_feeds.artist_id
INNER JOIN artists ON artists.id = artist_feeds.artist_id
WHERE artist_feeds.feed_date >= '2015-10-01'
AND user_artists.user_id = 486
AND NOT EXISTS (
SELECT id FROM user_artist_disabled_networks AS uadn
WHERE uadn.user_id = 486
AND uadn.artist_id = artist_feeds.artist_id
AND uadn.socialnetwork_id = artist_feeds.socialnetwork_id
LIMIT 1
)
ORDER BY artist_feeds.feed_date DESC
LIMIT 0, 20
该查询的解释如下所示;
任何人都可以提供任何指针?
根据要求,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`),
KEY `feed_date` (`feed_date`)
) ENGINE=InnoDB AUTO_INCREMENT=26991713 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
解决:感谢比尔指针,我研究能够改变的表中的表的访问顺序,使artist_feed表是第一台访问,这反过来将消除需要一个文件上的数据,这导致了速度的增加。
我结束了使用STRAIGHT_JOIN而不是INNER JOIN。我的工作查询是;
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 >= '2015-10-01'
AND uadn.user_id IS NULL
AND ua.user_id = 498
ORDER BY af.feed_date DESC
LIMIT 0, 20
说明现在看起来像这样;
我不是这方面的专家,但是如果您希望花费不到一秒,请添加3秒的超时时间并重试代码,然后开始调查。 –
我不希望查询花费少于一秒的时间。这是查询似乎需要多长时间才能完成的时间,但有时查询会挂起,然后导致查询队列落后。 – SheppardDigital
请求查询优化帮助时,请在查询中为每个表发布“SHOW CREATE TABLE”。它有助于我们理解您定义的数据类型,索引和约束条件,这是制定优化策略所必需的。 –