[英]Slow Execution of MySQL Select Query
I have the following query… 我有以下查询...
SELECT DISTINCT * FROM
vPAS_Posts_Users
WHERE (post_user_id =:id AND post_type != 4)
AND post_updated >:updated
GROUP BY post_post_id
UNION
SELECT DISTINCT vPAS_Posts_Users.* FROM PAS_Follow
JOIN vPAS_Posts_Users ON
( PAS_Follow.folw_followed_user_id = vPAS_Posts_Users.post_user_id )
WHERE (( PAS_Follow.folw_follower_user_id =:id AND PAS_Follow.folw_deleted = 0 )
OR ( post_type = 4 AND post_passed_on_by = PAS_Follow.folw_follower_user_id
AND post_user_id !=:id ))
AND post_updated >:updated
GROUP BY post_post_id ORDER BY post_posted_date DESC LIMIT :limit
Where :id = 7
, :updated = 0.0
and :limit=40
for example 例如
:id = 7
, :updated = 0.0
和:limit=40
My issue is that the query is taking about a minute to return results. 我的问题是查询需要大约一分钟才能返回结果。 Is there anything in this query that I can do to speed up the result?
此查询中有什么我可以做以加快结果的速度吗?
I am using RDS 我正在使用RDS
********EDIT********* ********编辑*********
I was asked to run the query with an EXPLAIN the result is below 我被要求使用EXPLAIN运行查询,结果如下
********EDIT********** View Definitition ******** EDIT **********查看定义
CREATE ALGORITHM=UNDEFINED DEFINER=`MySQLUSer`@`%` SQL SECURITY DEFINER VIEW `vPAS_Posts_Users`
AS SELECT
`PAS_User`.`user_user_id` AS `user_user_id`,
`PAS_User`.`user_country` AS `user_country`,
`PAS_User`.`user_city` AS `user_city`,
`PAS_User`.`user_company` AS `user_company`,
`PAS_User`.`user_account_type` AS `user_account_type`,
`PAS_User`.`user_account_premium` AS `user_account_premium`,
`PAS_User`.`user_sign_up_date` AS `user_sign_up_date`,
`PAS_User`.`user_first_name` AS `user_first_name`,
`PAS_User`.`user_last_name` AS `user_last_name`,
`PAS_User`.`user_avatar_url` AS `user_avatar_url`,
`PAS_User`.`user_cover_image_url` AS `user_cover_image_url`,
`PAS_User`.`user_bio` AS `user_bio`,
`PAS_User`.`user_telephone` AS `user_telephone`,
`PAS_User`.`user_dob` AS `user_dob`,
`PAS_User`.`user_sector` AS `user_sector`,
`PAS_User`.`user_job_type` AS `user_job_type`,
`PAS_User`.`user_unique` AS `user_unique`,
`PAS_User`.`user_deleted` AS `user_deleted`,
`PAS_User`.`user_updated` AS `user_updated`,
`PAS_Post`.`post_post_id` AS `post_post_id`,
`PAS_Post`.`post_language_id` AS `post_language_id`,
`PAS_Post`.`post_type` AS `post_type`,
`PAS_Post`.`post_promoted` AS `post_promoted`,
`PAS_Post`.`post_user_id` AS `post_user_id`,
`PAS_Post`.`post_posted_date` AS `post_posted_date`,
`PAS_Post`.`post_latitude` AS `post_latitude`,
`PAS_Post`.`post_longitude` AS `post_longitude`,
`PAS_Post`.`post_location_name` AS `post_location_name`,
`PAS_Post`.`post_text` AS `post_text`,
`PAS_Post`.`post_media_url` AS `post_media_url`,
`PAS_Post`.`post_image_height` AS `post_image_height`,
`PAS_Post`.`post_link` AS `post_link`,
`PAS_Post`.`post_link_title` AS `post_link_title`,
`PAS_Post`.`post_unique` AS `post_unique`,
`PAS_Post`.`post_deleted` AS `post_deleted`,
`PAS_Post`.`post_updated` AS `post_updated`,
`PAS_Post`.`post_original_post_id` AS `post_original_post_id`,
`PAS_Post`.`post_original_type` AS `post_original_type`,
`PAS_Post`.`post_passed_on_by` AS `post_passed_on_by`,
`PAS_Post`.`post_passed_on_caption` AS `post_passed_on_caption`,
`PAS_Post`.`post_passed_on_fullname` AS `post_passed_on_fullname`,
`PAS_Post`.`post_passed_on_avatar_url` AS `post_passed_on_avatar_url`
FROM (`PAS_User` join `PAS_Post` on((`PAS_User`.`user_user_id` = `PAS_Post`.`post_user_id`)));
try this query: 试试这个查询:
SELECT *
FROM
vPAS_Posts_Users
WHERE
post_user_id =:id
AND post_type != 4
AND post_updated > :updated
UNION
SELECT u.*
FROM vPAS_Posts_Users u
JOIN PAS_Follow f ON f.folw_followed_user_id = u.post_user_id
WHERE
u.post_updated > :updated
AND ( (f.folw_follower_user_id = :id AND f.folw_deleted = 0)
OR (u.post_type = 4 AND u.post_passed_on_by = f.folw_follower_user_id AND u.post_user_id != :id)
)
ORDER BY u.post_posted_date DESC;
LIMIT :limit
Indices: Be sure you have indices on the following columns: 索引:确保在以下列上有索引:
After that is done, please 1- check the performance again (SQL_NO_CACHE) and 2- extract another explain plan so we can adjust the query. 完成之后,请1-再次检查性能(SQL_NO_CACHE),然后2提取另一个说明计划,以便我们可以调整查询。
EXPLAIN Results 说明结果
Here are the some suggestions for the query and view first of all using the UNION
for the two result sets which might makes your query to work slow instead you can use the UNION ALL
以下是有关查询的一些建议,并首先对两个结果集使用
UNION
进行查看,这可能会使查询工作缓慢,而可以使用UNION ALL
Reason is both UNION ALL
and UNION
use temporary table for result generation.The difference in execution speed comes from the fact UNION
requires internal temporary table with index (to skip duplicate rows) while UNION ALL
will create table without such index.This explains the slight performance improvement when using UNION ALL
. 原因是
UNION ALL
和UNION
使用临时表来生成结果。执行速度的差异是因为UNION
要求内部临时表带有索引(以跳过重复的行),而UNION ALL
将创建不具有此类索引的表。使用UNION ALL
时的性能改进。 UNION
on its own will remove any duplicate records so no need to use the DISTINCT
clause, try to only one GROUP BY of the whole result set by subqueries this will also minimize the execution time rather then grouping results in each subquery. UNION
会自行删除所有重复的记录,因此无需使用DISTINCT
子句,仅尝试按子查询查询整个结果集中的一个GROUP BY,这也将最小化执行时间,而不是对每个子查询进行结果分组。
Make sure you have added the right indexes on the columns especially the columns used in the WHERE,ORDER BY, GROUP BY
, the data types should be appropriate for each column with respect to the nature of data in it like post_posted_date
should be datetime,date with an index also. 确保在列上添加了正确的索引,尤其是在
WHERE,ORDER BY, GROUP BY
中使用的列,相对于其中的数据性质,数据类型应该适合于每个列,例如post_posted_date
应该是datetime,date与索引也。
Here is the rough idea for the query 这是查询的基本思路
SELECT q.* FROM (
SELECT * FROM
vPAS_Posts_Users
WHERE (post_user_id =:id AND post_type != 4)
AND post_updated >:updated
UNION ALL
SELECT vPAS_Posts_Users.* FROM PAS_Follow
JOIN vPAS_Posts_Users ON
( PAS_Follow.folw_followed_user_id = vPAS_Posts_Users.post_user_id
AND vPAS_Posts_Users.post_updated >:updated)
WHERE (( PAS_Follow.folw_follower_user_id =:id AND PAS_Follow.folw_deleted = 0 )
OR ( post_type = 4 AND post_passed_on_by = PAS_Follow.folw_follower_user_id
AND post_user_id !=:id ))
) q
GROUP BY q.post_post_id ORDER BY q.post_posted_date DESC LIMIT :limit
References 参考
Difference Between Union vs. Union All – Optimal Performance Comparison Union与Union All之间的差异–最佳性能比较
From your explain I can see that most of your table don't have any key except for the primary one, I would suggest you to add some extra key on the columns you're going to join, for example on: PAS_Follow.folw_followed_user_id and vPAS_Posts_Users.post_user_id, just this will result in a big performance boost. 从您的解释中,我可以看到您的大多数表除了主键外没有其他键,我建议您在要连接的列上添加一些额外的键,例如:PAS_Follow.folw_followed_user_id和vPAS_Posts_Users.post_user_id,仅此将大大提高性能。
Bye, Gnagno 再见Gnagno
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.