【发布时间】:2020-01-02 11:34:36
【问题描述】:
大家好,
我正在努力解决以下问题,我非常感谢有关如何提高此查询性能的一些建议
SELECT
COUNT(*) AS `pageviews`,
COUNT(DISTINCT `sessions_events`.`session_id`) AS `sessions`,
COUNT(DISTINCT `sessions_events`.`visitor_id`) AS `visitors`,
`sessions_events`.`date_day`
FROM
`sessions_events`
LEFT JOIN
`websites_visitors` ON `sessions_events`.`visitor_id` = `websites_visitors`.`visitor_id`
WHERE
`sessions_events`.`website_id` = 1
AND (`sessions_events`.`date_day` BETWEEN '2019-12-01' AND '2019-12-31')
GROUP BY
`sessions_events`.`date_day`
我试图从中获取的表的当前状态如下所示:
我最初是 DATE_FORMAT(sessions_events.date, '%Y-%m-%d') AS formatted_date 并按 formatted_date 分组> 但我还创建了另一个 date_day,它只存储实际日期(没有 H:I:S)并摆脱 DATE_FORMAT() 的使用。 p>
此表 (sessions_events) 现在已在 5 个不同网站(每个 website_id 约 100 万行)中填充了 500 万行,因为我想测试性能。
完成上述查询大约需要 13-15 秒。
如果您询问 LEFT JOIN:我正在使用它,以防前端有人想要对选择应用过滤器,并且只检查从美国访问过的综合浏览量、会话和访问者(例如)。
这是我需要的数据的样子:
此数据用于生成显示特定日期范围内的综合浏览量、会话和访问者的图表。
对此的任何帮助将不胜感激,因为我只是看不出如何改进这一点..
再次感谢您!
【问题讨论】:
-
这很好。我认为你能期望的最好的结果是对 (visitor_id,website_id,date) 的某种排列的复合索引
-
感谢@Strawberry 的评论!尝试了这个,但不幸的是性能没有真正的变化。在您看来,这个性能是您能得到的最多的吗?
-
你试过
Explaindev.mysql.com/doc/refman/5.7/en/using-explain.html来找出可能的瓶颈吗? -
@BrainFooLong Yes -> i.imgur.com/hlqR9kb.png 但我个人无法从这个解释中找到任何额外的东西..
-
根据解释,它正在检查 210 万行,即使在索引优化搜索之后也是如此。无论如何,这将需要一段时间。也许剩下的唯一解决方案是 (a) 获得更快的服务器并为 InnoDB 缓冲池分配更多 RAM,或者 (b) 使用汇总表。