mysql - 提高大型 SQL 查询的效率

标签 mysql sql

我陷入了一个相当复杂的查询。

我正在编写一个查询,显示“前五个客户”以及有关每个客户的一些关键指标(带条件的计数)。每个不同的指标都使用完全不同的连接结构。

+-----------+------------+   +-----------+------------+    +-----------+------------+
| customer  |            |   | metricn   |            |    | metricn_lineitem       | 
+-----------+------------+   +-----------+------------+    +-----------+------------+
| id        | Name       |   | id        | customer_id|    |id         |metricn_id  |
| 1         | Customer1  |   | 1         | 1          |    | 1         | 1          |
| 2         | Customer2  |   | 2         | 2          |    | 2         | 1          |
+-----------+------------+   +-----------+------------+    +-----------+------------+

问题是我总是想按这个客户表进行分组。

我首先尝试将所有连接放入原始查询中,但该查询的性能非常糟糕。然后我尝试使用子查询,但无法让它们按原始医院 ID 进行分组。

这是一个示例查询

SELECT 
     customer.name, 

     (SELECT COUNT(metric1_lineitem.id) 
      FROM metric1 INNER JOIN metric1_lineitem 
      ON metric1_lineitem.metric1_id = metric1.id
      WHERE metric1.customer_id = customer_id
      ) as metric_1,

     (SELECT COUNT(metric2_lineitem.id) 
      FROM metric2 INNER JOIN metric2_lineitem 
      ON metric2_lineitem.metric2_id = metric2.id
      WHERE metric2.customer_id = customer_id
      ) as metric_2

FROM customer
GROUP BY customer.name
SORT BY COUNT(metric1.id) DESC
LIMIT 5

有什么建议吗?谢谢!

最佳答案

SELECT name, metric_1, metric_2
FROM customer AS c
LEFT JOIN (SELECT customer_id, COUNT(*) AS metric_1
           FROM metric1 AS m
           INNER JOIN metric1_lineitem AS l ON m.id = l.metric1_id
           GROUP BY customer_id) m1
ON m1.customer_id = c.customer_id
LEFT JOIN (SELECT customer_id, COUNT(*) AS metric_2
           FROM metric2 AS m
           INNER JOIN metric2_lineitem AS l ON m.id = l.metric2_id
           GROUP BY customer_id) m1
ON m2.customer_id = c.customer_id
ORDER BY metric_1 DESC
LIMIT 5

当您可以使用 COUNT(*) 代替时,您还应该避免使用 COUNT(columnname)。前者必须测试每个值以查看它是否为空。

关于mysql - 提高大型 SQL 查询的效率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21124340/

相关文章:

C# 从 Mysql 获取精确字符串不起作用

SQL - 将时间戳规范化为营业时间

sql - 我应该将此新列添加到客户表还是单独的新表?

php - 选择列最接近当前日期的 MySQL 行

mysql - 为什么vb.net中sql命令无法转换为mysql命令

MySQL 子选择并从子选择表中返回多条记录

php - MySQL - ENUM - ISO 3166-1 国家/地区代码的好主意?

android - 数据库流 'count as'

sql - SQL 中的感叹号 (Oracle)

php - 使 SQL 查询的第一个和最后一个结果唯一的最佳方法?