编写此查询的另一种方法是什么?
我的服务器需要花很多时间来执行这个:
SELECT c.id, c.franquicia_id, f.name, CONCAT(c.name,' ',c.surname)
contacto, c.created, DATE_FORMAT(c.created,'%d-%m-%Y') fecha
FROM franquicias f, contacts c where f.id = c.franquicia_id
and c.created = (
select max(c2.created)
from contacts c2
WHERE c2.franquicia_id = c.franquicia_id
)
and f.contract_id=2
ORDER BY created DESC
limit 10
答案 0 :(得分:2)
此版本的子查询只需要为整个查询运行一次,而不是外部查询的每一行。
SELECT c.id, c.franquicia_id, f.name
, CONCAT(c.name,' ',c.surname) AS contacto
, c.created, DATE_FORMAT(c.created,'%d-%m-%Y') AS fecha
FROM contacts AS c
INNER JOIN franquicias AS f
ON c.franquicia_id = f.id
AND f.contract_id=2
WHERE (c.franquicia_id, c.created) IN (
SELECT franquicia_id, max(created)
FROM contacts
GROUP BY franquicia_id
)
ORDER BY created DESC
LIMIT 10
或者,可以在子查询中使用子查询进行过滤。
f.contract_id=2
可以放入ON
或WHERE
;但是(并且优化器可以消除任何差异),将其保留在ON
可能可能减少在where中检查的行,并使以后更容易将查询转换为{{1如果需要找到"最近没有f' of contract_id 2"。
注意:索引LEFT JOIN
应该改进子查询,并使用(franquicia_id, created)
来对付它;它还应该改善IN
上的现有JOIN条件。
答案 1 :(得分:0)
引用此 Post
我个人认为INNER JOIN更好,因为它更多 可读。它表明了表格之间的关系。你得到了 在连接中的那些关系,并在WHERE中进行过滤 条款。这种分离使查询更具可读性。
SELECT
c.id,
c.franquicia_id,
f.name,
CONCAT(c.name,' ',c.surname) contacto,
c.created,
DATE_FORMAT(c.created,'%d-%m-%Y') fecha
FROM franquicias f
INNER JOIN contacts c ON f.id = c.franquicia_id
INNER JOIN
(
SELECT
C2.franquicia_id,
MAX(C2.created) max_created
FROM contacts C2
GROUP BY C2.franquicia_id
) AS maxCreatedForFrID
ON maxCreatedForFrID.franquicia_id = c.franquicia_id AND maxCreatedForFrID.max_created = c.created
WHERE f.contract_id = 2
ORDER BY created DESC
LIMIT 10;
注意:强>
franquicia_id,created
表中的复合索引(contacts
)可能会提高性能。
ALTER TABLE `contacts` ADD INDEX `idx_contacts_franquicia_id_created` (
`franquicia_id`,
`created`
);
答案 2 :(得分:0)
如果franquicias
包含的记录不多,则下一个查询必须更有效:
SELECT c.id, c.franquicia_id, f.name, CONCAT(c.name,' ',c.surname)
contacto, c.created, DATE_FORMAT(c.created,'%d-%m-%Y') fecha
FROM (
SELECT DISTINCT MAX(c2.created) as c2_created, f2.*
FROM contacts c2
JOIN franquicias f2 ON f2.id = c2.franquicia_id
) f
JOIN contacts c ON f.id = c.franquicia_id
AND c.created = f.c2_created
WHERE f.contract_id=2
ORDER BY created DESC
limit 10