MySQL Select查询执行缓慢

MySQL Select查询执行缓慢,mysql,performance,pdo,Mysql,Performance,Pdo,我有以下疑问 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.fol

我有以下疑问

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
例如,其中
:id=7
:updated=0.0
:limit=40

我的问题是,查询返回结果大约需要一分钟的时间。在这个查询中,我可以做些什么来加速结果

我正在使用RDS

********编辑*********

我被要求运行查询并解释结果如下

********编辑********** 视图定义

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`)));
请尝试以下查询:

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

其他改进 索引: 确保在以下列上有索引:

  • PAS_User.User_User_id
  • PAS\U Post.Post\U用户\U id
  • PAS_Post.Post_类型
  • PAS_Post.Post_更新
  • PAS_Follow.Follow_Follow_用户id
  • PAS_Follow.folw_已删除
  • 通过了
完成后,请1-再次检查性能(SQL\u NO\u缓存),2-提取另一个解释计划,以便我们可以调整查询


解释结果


从您的解释中,我可以看出,您的大多数表除了主表外没有任何键,我建议您在要加入的列上添加一些额外的键,例如:PAS_Follow.folw_followerd_user_id和vPAS_Posts_Users.post_user_id,这将大大提高性能

再见,
Gnagno

以下是一些关于查询和查看的建议,首先对两个结果集使用
UNION
,这可能会使您的查询速度变慢。您可以使用
UNION all

为什么我指的是你使用联合所有 原因是
UNION ALL
UNION
使用临时表生成结果。执行速度的差异来自于
UNION
需要带索引的内部临时表(跳过重复行)而
UNION ALL
将创建没有此类索引的表。这解释了使用
UNION ALL
时性能略有改善的原因。
UNION
本身将删除任何重复的记录,因此无需使用
DISTINCT
子句,尝试只对子查询的整个结果集进行一次分组,这也将最大限度地减少执行时间,而不是在每个子查询中对结果进行分组

确保在列上添加了正确的索引,尤其是在
中使用的列,其中,ORDER BY、GROUP BY
,数据类型应适合每列中数据的性质,如
post_posted_date
应为datetime,date还应具有索引

下面是查询的大致思路

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
参考资料


您能告诉我为什么需要distinct*,这个表中有多少字段,我会说将它限制在您想要的字段中,这样可以稍微改进查询。此外,为什么您需要一个group by和一个distinct,这样做有特定的目的吗?总之,不,我多次构建查询以获得我想要的结果,但我没有真正关注这一点,这会导致问题吗?这里有很多麻烦,可能会使您的查询性能不佳。首先,不要使用
选择*
。当然不要使用
selectdistinct*
。命名您的列。其次,您的
分组依据
子句的目的是什么?你的聚合表达式在哪里?阅读以下内容:然后,避免使用非标准扩展。第三,
子句可以影响性能。第四,请解释您试图做什么,并披露您的表布局。@OllieJones谢谢您的回复,group by的目的是确保只有唯一的结果,因为视图会为每个帖子生成多个重复行。请发布视图定义-您有权更改这些返回的结果吗(例如,删除重复项)?谢谢你能对查询进行进一步迭代以生成一个工作版本吗?因为这似乎与组有问题。这很好,它将我的查询时间缩短到了10秒,我可以在这里进行进一步优化以加快速度吗?@JustinErswell添加限制子句,然后重试并告诉我结果,请告诉我我10秒的结果这是史诗般的,我们现在在465毫秒内运行此查询,感谢您在这里的帮助!我们甚至可以超越。我怀疑order by和limit子句之间存在冲突。请提取新的解释计划好吗?