你能避免mysql上的子查询以获得更好的性能吗?

r55awzrz  于 2021-06-21  发布在  Mysql
关注(0)|答案(2)|浏览(361)

我必须在一个查询结果上添加3个日期,但这些日期在另一个表的不同行上。
表comp

+---------+-------------+----------+
| id_comp | comp_status | comp_guy |
+---------+-------------+----------+
| 456     | 8           | 23       |
| 457     | 7           | 67       |
| 458     | 3           | 34       |
+---------+-------------+----------+

表eva

+--------+---------+----------+------------+
| id_eva | id_comp | eva_type | eva_date   |
+--------+---------+----------+------------+
| 3456   | 456     | 1        | 2018-01-09 |
| 3457   | 456     | 2        | 2018-01-12 |
| 3458   | 456     | 3        | 2018-01-11 |
| 3459   | 457     | 1        | 2018-01-09 |
| 3460   | 457     | 2        | 2018-01-03 |
| 3461   | 457     | 3        | 2018-01-02 |
+--------+---------+----------+------------+

我使用这样的查询:

select 
comp.id_comp,
(select eva.eva_date from eva where eva.eva_type = 1 and eva.id_comp = comp.id_comp) as eva_one
(select eva.eva_date from eva where eva.eva_type = 2 and eva.id_comp = comp.id_comp) as eva_two
(select eva.eva_date from eva where eva.eva_type = 3 and eva.id_comp = comp.id_comp) as eva_thr
comp.status,
comp.guy
from
comp
left join eva on (eva.id_comp = comp.id_comp)

结果:

+---------+-------------+-------------+------------+--------+-----+
| id_comp | eva_one     | eva_two     | eva_thr    | status | guy |
+---------+-------------+-------------+------------+--------+-----+
| 456     | 2018-01-09  | 2018-01-12  | 2018-01-11 | 8      | 23  |
| 457     | 2018-01-09  | 2018-01-03  | 2018-01-02 | 7      | 67  |
+---------+-------------+-------------+------------+--------+-----+

有没有办法避免这3个子查询?结果太慢了。

pw9qyyiw

pw9qyyiw1#

如果是我,我可能会使用如下查询,并在应用程序代码中处理任何进一步的显示逻辑(假设该逻辑可用)。。。

SELECT c.*
     , e.eva_type
     , e.eva_date 
  FROM comp c 
  LEFT 
  JOIN eva e 
    ON e.id_comp = c.id_comp;

对于任何有关性能的进一步问题,我们确实需要看到相关表的showcreatetable语句,以及首选查询的explain结果。

fykwrbwg

fykwrbwg2#

以下是数据透视查询的示例:

SELECT 
comp.id_comp,
MAX(CASE eva.eva_type WHEN 1 THEN eva.eva_date END) AS eva_one,
MAX(CASE eva.eva_type WHEN 2 THEN eva.eva_date END) AS eva_two,
MAX(CASE eva.eva_type WHEN 3 THEN eva.eva_date END) AS eva_thr,
comp.status,
comp.guy
FROM comp
JOIN eva ON (eva.id_comp = comp.id_comp)
GROUP BY comp.id_comp

在MySQL5.7上测试,sql\ U模式包括 ONLY_FULL_GROUP_BY . mysql 5.7可以推断comp.status和comp.guy在功能上依赖于comp.id\u comp,假设后者是主键。
输出:

+---------+------------+------------+------------+--------+------+
| id_comp | eva_one    | eva_two    | eva_thr    | status | guy  |
+---------+------------+------------+------------+--------+------+
|     456 | 2018-01-09 | 2018-01-12 | 2018-01-11 |      8 |   23 |
|     457 | 2018-01-09 | 2018-01-03 | 2018-01-02 |      7 |   67 |
+---------+------------+------------+------------+--------+------+

不清楚您是打算使用内部联接还是左外部联接。您在问题中显示了left[outer]join,但结果没有包含comp\u id 458的行,可能是因为eva中没有该comp\u id的行?这意味着内部连接。

相关问题