Mysql OneToMany仅加入最近的记录

时间:2017-11-10 05:03:51

标签: mysql query-optimization groupwise-maximum

我有两个表contactssubquery。客户可以拥有许多联系方式。在一个案例中,我只需要获得客户的最后添加的联系人详细信息。我可以通过+-------------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------------------+--------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | company_name | varchar(150) | NO | | NULL | | | logo | varchar(100) | NO | | NULL | | +-------------------+--------------+------+-----+---------+----------------+ 获得此信息。但是当数据量很大时,我面临的表现就是缺乏对所有客户数据的查询。

  

客户表(customers_customers)

+-------------+--------------+------+-----+---------+----------------+
| Field       | Type         | Null | Key | Default | Extra          |
+-------------+--------------+------+-----+---------+----------------+
| id          | int(11)      | NO   | PRI | NULL    | auto_increment |
| email       | varchar(100) | YES  |     | NULL    |                |
| mobile      | varchar(50)  | YES  |     | NULL    |                |
| customer_id | int(11)      | NO   | MUL | NULL    |                |
+-------------+--------------+------+-----+---------+----------------+
  

联系人表格(customers_customercontacts)

SELECT
    c.id,
    c.company_name,
    d.mobile
FROM customers_customers AS c
LEFT JOIN customers_customercontacts AS d
    ON d.id = (SELECT MAX(id) FROM customers_customercontacts WHERE d.customer_id = d.id);

我已尝试过以下查询,我收到了结果,但查询速度很慢。

SELECT
    c.id,
    c.company_name,
    d.mobile
FROM customers_customers AS c
LEFT JOIN customers_customercontacts AS d
    ON d.id = (SELECT id FROM customers_customercontacts WHERE d.customer_id = d.id
               ORDER BY id DESC LIMIT 1);

conn.setRequestMethod("GET");
conn.setDoInput(true)

我需要获取客户的company_names以及每个company_names的最后添加的phone_number。 有没有使用子查询的优化方法或方法来达到这个目的?

  

解决

NonCorrelated子查询总是比相关子查询具有更好的性能。

1 个答案:

答案 0 :(得分:1)

使用第二个连接到子查询,该子查询标识每个客户的最新联系人记录:

SELECT
    c.id,
    c.company_name,
    d1.mobile
FROM customers_customers AS c
LEFT JOIN customers_customercontacts AS d1
    ON c.id = d1.customer_id
INNER JOIN
(
    SELECT customer_id, MAX(id) AS max_id
    FROM customers_customercontacts
    GROUP BY customer_id
) AS d2
    ON d1.customer_id = d2.customer_id AND
       d1.id = d2.max_id;

这是对您的第一次查询尝试的修改。请注意,您的连接条件已被破坏,因为它并未真正与客户和联系人表关联。基本联接应与customers_customers.id匹配customers_customercontacts.customer_id。除了此更正之外,我还会进行额外的加入以限制每个客户的最新联系记录。

此方法可能提高性能的一个原因是此查询使用非相关子查询来查找每个客户的最新联系人。您的原始尝试使用了相关的子查询,这些子查询往往效果不佳。