mysql - 请优化多连接查询

标签 mysql sql query-optimization average

我对 sql 进行了查询,但它真的很重,我真的不知道如何优化它,解释如下:

SELECT tyds.user_tyd, 
       tyds.product_tyd, 
       tyds.action_tyd, 
       products.price_product, 
       data_8, 
       data_9, 
       avg_8, 
       sum_9 
FROM   tyds 
       INNER JOIN products 
               ON tyds.product_tyd = products.id_product 
       INNER JOIN (SELECT product_tyd, 
                          Avg(data_tyd) AS avg_8 
                   FROM   tyds 
                   WHERE  action_tyd = 8 
                   GROUP  BY product_tyd) Agg_1 
               ON Agg_1.product_tyd = tyds.product_tyd 
       INNER JOIN (SELECT product_tyd, 
                          Sum(data_tyd) AS sum_9 
                   FROM   tyds 
                   WHERE  action_tyd = 9 
                   GROUP  BY product_tyd) Agg_2 
               ON Agg_2.product_tyd = tyds.product_tyd 
       INNER JOIN (SELECT product_tyd, 
                          data_tyd AS data_8 
                   FROM   tyds 
                   WHERE  user_tyd = 3 
                          AND action_tyd = 8) Agg_3 
               ON Agg_3.product_tyd = tyds.product_tyd 
       INNER JOIN (SELECT product_tyd, 
                          data_tyd AS data_9 
                   FROM   tyds 
                   WHERE  user_tyd = 3 
                          AND action_tyd = 9) Agg_4 
               ON Agg_4.product_tyd = tyds.product_tyd 
WHERE  tyds.user_tyd = 3 
       AND tyds.action_tyd = 1 
GROUP  BY tyds.product_tyd 

所有这些关节是因为我需要得到很多东西: 我在 tyds.user_tyd = 3 中定义了一个 id_user tyds.action_tyd = 1 因为我想按 tyds.product_tyd 分组,其中前一个 id_user 作为 tyds.action_tyd = 1。

然后我想要: -data_8 是 tyds.data_tyd 的值,其中 user_tyd = 3 AND action_tyd = 8 -同样适用于 data_9

-对于 AVG 和 COUNT,我想跳过 tyds.user_tyd 条件,只按 id_product 分组。

实际上,这个查询是有效的,但我认为它真的很重而且有太多的 SELECT...

我一个月前提出了一个类似的问题,但我不得不审查我的架构,所以我很抱歉...

非常感谢。

e1 : 我用的是 MySQL

最佳答案

您实际上并不需要所有这些连接和子查询;您可以通过使用 CASE expressions 将逻辑从 WHERE 子句移动到字段列表中来消除其中的大部分:

SELECT 3 AS user_tyd, tyds.product_tyd, 1 AS action_tyd,
       products.price_product,
       MAX(CASE WHEN user_tyd = 3 AND action_tyd = 8 THEN data_tyd END) data_8,
       MAX(CASE WHEN user_tyd = 3 AND action_tyd = 9 THEN data_tyd END) data_9,
       AVG(CASE WHEN action_tyd = 8 THEN data_tyd END) AS avg_8,
       SUM(CASE WHEN action_tyd = 9 THEN data_tyd END) AS sum_9
  FROM tyds
  JOIN products
    ON tyds.product_tyd = products.id_product
 WHERE tyds.product_tyd IN
         ( SELECT product_tyd
             FROM tyds
            WHERE tyds.user_tyd = 3
              AND tyds.action_tyd = 1
         )
 GROUP
    BY tyds.product_tyd
;

(注意:第三行和第四行中的 MAX(...) 只是一种强制非空值优先于空值的方法。)

您必须测试看看这是否真的更快,但我敢打赌它是。

关于mysql - 请优化多连接查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12098148/

相关文章:

mysql - 在 sql 文件中设置 MySQL 分隔符

sql - 如何从 SQL Server 2012 中表的一个分区获取 COUNT(*)?

mysql - 优化foreach内的sql查询

mysql - 优化MySQL单表2800万行聚合查询

php - 显示赞助商服务器不同的颜色不显示 php

mysql - 有没有更好的方法来执行此 MySQL 查询?

php - 当有多少表时如何选择查询

mysql - 想要一个解决方案使用单个查询分别查找高于限制和低于限制的计数

mysql - Golang mysql select * 语句只返回第一个值

mysql - 审计触发器,将 Blob 作为 LongText 插入