我是查询优化的新手,所以我阅读了很多文章并观看了YouTubes和其他内容,但我仍然无法弄明白。
问题是我想要为我的API执行此查询:
SELECT req_id,follow_requests.insta_id as id,caption,follow_requests.male,
users.name,users.profile_pic
FROM follow_requests
INNER JOIN users ON follow_requests.insta_id = users.insta_id
WHERE (remaining_follow>0 && req_id<='574989')
AND NOT EXISTS
(
SELECT *
FROM follows
WHERE follows.req_id=follow_requests.req_id
AND follows.follower_insta_id='3134816134'
)
ORDER BY req_id DESC
LIMIT 20
所以我记录了我的数据库并且摘要显示这个正在吃+ 42%的资源 这个查询的一些实例看起来像300秒,它平均有20秒!(他们在发送数据状态时遇到困难) 所以我试着更好地改变它(不是我真的知道我在做什么:) 我把它改成了这个
SELECT fr.req_id, fr.insta_id as id, fr.caption, fr.male, u.name,
u.profile_pic, fr.date, fr.remaining_follow
FROM follow_requests AS fr
INNER JOIN users AS u ON fr.insta_id=u.insta_id
WHERE fr.remaining_follow>0
AND fr.insta_id!=3134816134
AND NOT EXISTS
(
SELECT *
FROM follows as f
WHERE f.req_id=fr.req_id
AND f.follower_insta_id='3134816134'
)
ORDER BY fr.date DESC
LIMIT 20
奇怪的是,前几次运行没问题!比如从0.1秒到0.7秒
在测试运行
但是在我伸展一下然后回来完成它之后,这也被卡住了+200,300秒,但是这次是排序状态
我用解释检查了查询,我注意到它没有使用日期索引!
如果我只从查询中删除'order by'部分,它变得非常快~0.2s
任何想法?
顺便说一句,几乎所有的列都被编入索引,并且跟随表有2M行,其他类似于+ 100k
抱歉如果我无法解释它或者我错过了给你一些重要信息,我只是新的;)
如果您能以某种方式解释新手可以理解的同时不会遗漏重要细节,我将非常感激:)
提前致谢
= - = - = - = - = - = - =更新1 = - = - = - = - = - = - =
感谢你的帮助,我现在达到了这个查询的时间效率,但是 我不得不改变整个事情,但它可能仍有问题
SELECT follow_requests.req_id, follow_requests.insta_id as id,
caption, follow_requests.male, users.name,users.profile_pic
FROM follow_requests
INNER JOIN users ON follow_requests.insta_id = users.insta_id
LEFT OUTER JOIN follows ON follows.req_id = follow_requests.req_id
AND follows.follower_insta_id = '3134816134'
WHERE follow_requests.remaining_follow >0
AND follow_requests.insta_id != 3134816134
AND (follows.follower_insta_id != 3134816134 || follows.follower_insta_id is null)
ORDER BY follow_requests.date DESC
LIMIT 20
嗯,首先我需要说我没有写原始查询(第1个)而我自己并不了解所有这些:/但主程序员现在已经无法触及我必须取代他的位置或者整个项目将失败
关于问题是每个人都可以提交多个insta_id请求,但是应该只返回其中一个 主代码和@Kickstart代码(原始代码的优化版本,大约10秒的响应时间)是正确的(由于某种原因,我不明白 但我的代码返回相同insta_id的多个实例(使用不同的req_id)
还有一些机构可以告诉我为什么第一个查询做得那么糟糕?
答案 0 :(得分:0)
我有两个解决方案
1ST:
而不是使用&#34;选择*&#34;使用&#34;选择id&#34;
SELECT fr.req_id, fr.insta_id as id, fr.caption, fr.male, u.name, u.profile_pic, fr.date, fr.remaining_follow
FROM follow_requests AS fr INNER JOIN users AS u
ON fr.insta_id=u.insta_id
WHERE fr.remaining_follow>0 AND fr.insta_id!=3134816134
AND NOT EXISTS (SELECT f.id FROM follows as f WHERE f.req_id=fr.req_id AND f.follower_insta_id='3134816134')
ORDER BY fr.date DESC LIMIT 20
2ND:
你可以做到这一点
SELECT fr.req_id,
fr.insta_id AS id,
fr.caption,
fr.male,
u.name,
u.profile_pic,
fr.date,
fr.remaining_follow
FROM follow_requests AS fr
INNER JOIN users AS u
ON fr.insta_id = u.insta_id
INNER JOIN follows AS f
ON f.req_id = fr.req_id
AND f.follower_insta_id != '3134816134'
WHERE fr.remaining_follow > 0
AND fr.insta_id != 3134816134
ORDER BY fr.date DESC
LIMIT 20
答案 1 :(得分:0)
真的需要查看表声明和查询的EXPLAIN。
然而,可能值得尝试下表的LEFT OUTER JOIN,并检查不匹配(通过检查必须在该表上填充的列为NULL)。
但是,您在下表中有一个索引,它包含req_id和follower_insta_id字段吗?不是2个单独的索引,而是覆盖两个字段的索引。
SELECT req_id,
follow_requests.insta_id as id,
caption,
follow_requests.male,
users.name,users.profile_pic
FROM follow_requests
INNER JOIN users ON follow_requests.insta_id = users.insta_id
LEFT OUTER JOIN follows ON follows.req_id = follow_requests.req_id AND follows.follower_insta_id = '3134816134'
WHERE follows.req_id IS NULL
AND remaining_follow > 0
AND req_id <= '574989'
ORDER BY req_id DESC
LIMIT 20
答案 2 :(得分:0)
解释@Kickstart代码
EXPLAIN SELECT follow_requests.req_id,
follow_requests.insta_id as id,
caption,
follow_requests.male,
users.name,users.profile_pic
FROM follow_requests
INNER JOIN users ON follow_requests.insta_id = users.insta_id
LEFT OUTER JOIN follows ON follows.req_id = follow_requests.req_id AND follows.follower_insta_id = '3134816134'
WHERE remaining_follow > 0
AND follow_requests.req_id <= '574989'
ORDER BY follow_requests.req_id DESC
LIMIT 20
1 SIMPLE follow_requests index PRIMARY,insta_id,remaining_follow,remaining_follow... PRIMARY 8 6812 Using where
1 SIMPLE follows ref follower_insta_id,req_id,follower_insta_id_req_id follower_insta_id_req_id 17 insta_star.follow_requests.req_id,const 1 Using index
1 SIMPLE users eq_ref PRIMARY,insta_id PRIMARY 8 insta_star.follow_requests.insta_id 1
答案 3 :(得分:0)
对此有什么想法吗?
SELECT lr.req_id, lr.insta_id AS id, u.name AS username, lr.media_id,
lr.caption, lr.male
FROM like_requests AS lr use INDEX (remaining_like)
INNER JOIN users AS u ON lr.insta_id=u.insta_id
LEFT OUTER JOIN likes AS l ON l.req_id = lr.req_id
AND l.insta_id = 4021226743
WHERE lr.remaining_like>0
AND lr.req_id<459537
AND lr.insta_id!=4021226743
AND (l.insta_id!=4021226743 || l.insta_id is null)
AND lr.active=1
AND NOT EXISTS
(
SELECT *
FROM like_reports
WHERE insta_id=4021226743
AND like_reports.req_id=lr.req_id
)
ORDER BY lr.req_id DESC
LIMIT 10
说明:
id, select_type, table, type, possible_keys, key, key_len, ref, rows, extra
------------------------------------------------------------------------
1 PRIMARY lr range remaining_like remaining_like 4 NULL 1056 Using index condition; Using where; Using filesort
1 PRIMARY l ref req_id,insta_id,req_id_insta_id req_id_insta_id 16 insta_star.lr.req_id,const 1 Using where; Using index
1 PRIMARY u eq_ref PRIMARY,insta_id PRIMARY 8 insta_star.lr.insta_id 1
2 MATERIALIZED like_reports ref req_id,insta_id,insta_id_req_id insta_id_req_id 8 const 1 Using index
哇,花了很多时间来调整它们?你们怎么出口到那些美丽的桌子形状?
=====更新=====
可能是因为大量用户使用API?现在它的夜晚我仍然有网上活跃用户我不知道也许-500(完全不知道) 但是每件事情都不顺利,没有挂起的查询过程? 我应该升级什么? 硬?内存 ?中央处理器? 我怎么知道其中一个是否缺乏?
=======更新2 ======
添加了表格结构
CREATE TABLE `like_requests` (
`req_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`insta_id` bigint(20) unsigned NOT NULL,
`media_id` varchar(50) NOT NULL,
`remaining_like` int(10) unsigned NOT NULL,
`active` tinyint(10) NOT NULL DEFAULT '1',
`count` int(10) unsigned NOT NULL,
`date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`caption` text CHARACTER SET utf8 COLLATE utf8_unicode_ci,
`male` tinyint(4) DEFAULT NULL,
PRIMARY KEY (`req_id`),
KEY `insta_id` (`insta_id`),
CONSTRAINT `like_requests_ibfk_1` FOREIGN KEY (`insta_id`) REFERENCES `users` (`insta_id`)
CREATE TABLE `likes` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`insta_id` bigint(20) unsigned NOT NULL,
`media_id` varchar(50) NOT NULL,
`req_id` bigint(20) unsigned NOT NULL,
`date` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`),
KEY `req_id` (`req_id`),
KEY `insta_id` (`insta_id`),
CONSTRAINT `likes_ibfk_1` FOREIGN KEY (`req_id`) REFERENCES `like_requests` (`req_id`),
CONSTRAINT `likes_ibfk_2` FOREIGN KEY (`insta_id`) REFERENCES `users` (`insta_id`)
) ENGINE=InnoDB AUTO_INCREMENT=7931674 DEFAULT CHARSET=latin1;
CREATE TABLE `users` (
`insta_id` bigint(20) unsigned NOT NULL,
`name` varchar(50) NOT NULL,
`token` varchar(60) NOT NULL,
`gem` int(10) NOT NULL DEFAULT '10',
`coin` int(10) NOT NULL DEFAULT '10',
`latitude` double DEFAULT NULL,
`longitude` double DEFAULT NULL,
`notif_token` varchar(50) DEFAULT NULL,
`male` tinyint(1) DEFAULT NULL,
`last_gotten_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`profile_pic` text,
PRIMARY KEY (`insta_id`),
UNIQUE KEY `insta_id` (`insta_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;