SELECT total_fan_count
FROM users social_users
JOIN entities_users seu
ON seu.user_id = social_users.id
JOIN entities social_influencers
ON social_influencers.id = seu.entity_id
LEFT
JOIN influencers_socialstats sss
ON sss.influencer_user_id = social_users.id
LEFT
JOIN setup_socialmedia_channels ssc
ON ssc.id = sss.setup_socialmedia_channel_id
WHERE social_influencers.id = influencers.id
AND ssc.code_name = 'facebook'
GROUP
BY influencers.id
SELECT
<dependent subquery1> as campaigns_completed,
<dependent subquery2> as total_fan_count,
...
t.*
FROM (
<the rest of your query>
ORDER BY
Field( countries.id, 231 ) DESC
LIMIT 25 OFFSET 0
) t
ALTER TABLE `campaigns_offered_influencers` ADD INDEX `campaigns_offered_in_idx_status_id` (`campaign_offered_status`,`user_id`);
ALTER TABLE `entities` ADD INDEX `entities_idx_type_statu_id_id_id_id` (`entity_type`,`row_status`,`id`,`rating_id`,`country_id`,`states_id`);
ALTER TABLE `entities` ADD INDEX `entities_idx_id` (`id`);
ALTER TABLE `entities_users` ADD INDEX `entities_users_idx_id_id` (`user_id`,`entity_id`);
ALTER TABLE `entities_users` ADD INDEX `entities_users_idx_id` (`id`);
ALTER TABLE `entities_users_roles` ADD INDEX `entities_users_roles_idx_id_id` (`user_id`,`role_id`);
ALTER TABLE `favourite_influencers` ADD INDEX `favourite_influencer_idx_id_status` (`entity_id`,`row_status`);
ALTER TABLE `file_attachments` ADD INDEX `file_attachments_idx_id` (`id`);
ALTER TABLE `influencer_interests` ADD INDEX `influencer_interests_idx_id_id` (`entity_id`,`interest_groups_id`);
ALTER TABLE `influencers_audience_location` ADD INDEX `influencers_audience_idx_id_id_id_id` (`user_id`,`country_id`,`state_id`,`city_id`);
ALTER TABLE `influencers_socialstats` ADD INDEX `influencers_socialst_idx_id_id_id` (`influencer_user_id`,`setup_socialmedia_channel_id`,`setup_social_engagement_rate_id`);
ALTER TABLE `setup_cities` ADD INDEX `setup_cities_idx_id_name` (`id`,`city_name`);
ALTER TABLE `setup_countries` ADD INDEX `setup_countries_idx_id_name_2_3` (`id`,`country_name`,`iso_code_2`,`iso_code_3`);
ALTER TABLE `setup_interest_groups` ADD INDEX `setup_interest_group_idx_id_id_name` (`id`,`parent_id`,`interest_name`);
ALTER TABLE `setup_rating_list` ADD INDEX `setup_rating_list_idx_id_value` (`id`,`display_value`);
ALTER TABLE `setup_roles` ADD INDEX `setup_roles_idx_id_name_name` (`id`,`code_name`,`role_name`);
ALTER TABLE `setup_social_engagement_levels` ADD INDEX `setup_social_engagem_idx_id` (`id`);
ALTER TABLE `setup_socialmedia_channels` ADD INDEX `setup_socialmedia_ch_idx_id` (`id`);
ALTER TABLE `setup_states` ADD INDEX `setup_states_idx_id_name` (`id`,`state_name`);
ALTER TABLE `users` ADD INDEX `users_idx_status_verified_id` (`row_status`,`account_verified`,`id`);
ALTER TABLE `users` ADD INDEX `users_idx_id` (`id`);
CREATE TEMPORARY TABLE tfc
( PRIMARY KEY code_name )
SELECT ssc.code_name, total_fan_count
FROM users AS social_users
INNER JOIN entities_users AS seu
ON seu.user_id = social_users.id
GROUP BY seu.entity_id
通过一次传递,这可能比所有相关的子查询快得多。 然后使用更简单的查询来获得每列的总粉丝数。 将旋转视为一个单独的步骤 看待这个问题的另一种方法是分两步来完成这个过程;第二个是“旋转”。 先做限制 另一个技巧是从找到你需要的25个ID开始。也就是说,编写最少的sql来获取 LIMIT 实现。那么 JOIN 其他的东西。这可能只允许25次查找,等等。这可能会绕过您提到的74s对6s计时。它也可能因为其他原因而缩短时间。 不要过度正常化 将“locations”分散到多个表(城市+州+国家)而不是单个locations表,会导致系统中的大量额外工作 SELECT 在太空或其他方面几乎没有好处(一个城市的名字多久换一次?事实或后果,尽管如此。) 小心充气放气 JOIN 增大正在处理的行数,只会让您执行 GROUP BY 一定要把它缩小到你需要的程度。我以前的一些评论提到了这种综合征,但可能还涉及其他方面。
4条答案
按热度按时间sycxhyv71#
让我们检查一下您的查询的一个方面:
一些观察结果:
这是一个相关子查询。将其重写为不相关的子查询可能有助于提高性能。
您有一个GROUPBY子句,但没有聚合函数。在本例中,这可能无关紧要,因为您只选择了一列—但group by中的列集与select中的未聚合列集不同,这一点非常奇怪。
在左联接表(scc)上有一个where子句。这是矛盾的。要么将条件移到on子句,要么切换到内部联接。
我只检查了这一部分,很小的一部分,但是如果这些类型的错误(2和3)在您的查询中大量存在,那么我不希望它真的返回一个有效的结果-无论是快速还是其他。我建议您重新开始,逐个构建查询,并观察性能是否受到影响。
z2acfund2#
mysql正在为每一行执行依赖子查询,但是您只需要前25个。如果顺序不依赖于这些(实际情况是这样的),可以通过将顺序/限制移动到子查询来避免这种情况:
5cnsuln73#
几项建议:
有一些冗余的左连接可以删除(例如,
setup_influencer_types
). 删除它们可以显著提高性能(更少的连接=更少的数据库工作)。在限制之后(而不是之前)执行select子句中的查询会有很大帮助,因为这些查询在每个select行执行一次。下面的优化查询包含该修改。
一些连接可以是内部连接,而不是左连接(因为过滤是在它们上完成的,所以左连接它们没有意义)。内部连接的优点是,您可以为优化器提供更多选项来选择执行顺序。在大多数情况下,你最终会有一个更好的执行计划。
在这里阅读如何更好地优化分页的limit&offset子句。
因此,总结一下,首先添加这些优化查询所需的索引:
然后,尝试运行这个优化的查询(我使用了pastebin,因为查询太长,超出了stackoverflow的限制)。
p、 我使用eversql优化了这个查询(用于索引和查询建议)。免责声明:我是eversql的联合创始人。
lnxxn5zx4#
单次通过获得风扇数量
所有这些相关的子查询(?)都可以滚动到
通过一次传递,这可能比所有相关的子查询快得多。
然后使用更简单的查询来获得每列的总粉丝数。
将旋转视为一个单独的步骤
看待这个问题的另一种方法是分两步来完成这个过程;第二个是“旋转”。
先做限制
另一个技巧是从找到你需要的25个ID开始。也就是说,编写最少的sql来获取
LIMIT
实现。那么JOIN
其他的东西。这可能只允许25次查找,等等。这可能会绕过您提到的74s对6s计时。它也可能因为其他原因而缩短时间。不要过度正常化
将“locations”分散到多个表(城市+州+国家)而不是单个locations表,会导致系统中的大量额外工作
SELECT
在太空或其他方面几乎没有好处(一个城市的名字多久换一次?事实或后果,尽管如此。)小心充气放气
JOIN
增大正在处理的行数,只会让您执行GROUP BY
一定要把它缩小到你需要的程度。我以前的一些评论提到了这种综合征,但可能还涉及其他方面。