0

我有两张桌子customers和他们的contacts. 一个客户可以有许多联系方式。在这种情况下,我只需要为客户获取最后添加的联系方式。我可以通过subquery. 但是当数据很大时,我在查询所有客户数据时面临性能不足的问题。

客户表 (customers_customers)

+-------------------+--------------+------+-----+---------+----------------+
| 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_customercontacts)

+-------------+--------------+------+-----+---------+----------------+
| 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    |                |
+-------------+--------------+------+-----+---------+----------------+

我已经尝试了以下查询,我得到了结果,但是查询很慢。

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);

我需要获取客户的公司名称和每个公司名称的最后添加的电话号码。是否有任何优化的方式或不使用子查询的方式来实现这一目标?

解决了

非相关子查询总是比相关子查询提供更好的性能。

4

1 回答 1

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. 在此更正的基础上,我进行了额外的联接以限制每个客户的最新联系记录。

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

于 2017-11-10T05:14:16.930 回答