느린 MySQL 쿼리 (MySQL 5 이상)에서 문제가 발생했습니다. 3 개의 테이블을 생각해 봅시다 :MySQL의 하위 쿼리와 내부 조인 속도가 느림
내 목표는 하나의 쿼리와 고객 당 한 줄로 모든 주소와 연락처 정보를 수집하는 것입니다. (~에 대한 각 테이블 7000 항목)을 완료하는 데이 쿼리 130 초 동안했다
SELECT customers.id_customer,
customers.name,
X.contact AS contact,
Y.street,
Y.zipcode,
Y.city
FROM customers
LEFT JOIN
(
SELECT
GROUP_CONCAT(CONCAT(type, ': ', value) SEPARATOR ', ') AS contact,
id_customer
FROM customers_contacts
GROUP BY id_customer
) AS X
ON X.id_customer = customers.id_customer
LEFT JOIN
(
SELECT
GROUP_CONCAT(street SEPARATOR '<br>') AS street,
GROUP_CONCAT(zipcode SEPARATOR '<br>') AS zipcode,
GROUP_CONCAT(city SEPARATOR '<br>') AS city,
id_customer
FROM customers_addresses
GROUP BY id_customer
) AS Y
ON Y.id_customer = customers.id_customer
WHERE Y.street LIKE '%Avenue%'
ORDER BY customers.name DESC
LIMIT 0, 20
까지 인 : 내 첫 번째 시도는 일부 고객 정보를 어떤 주소가 및/또는 접촉하지 않는 LEFT JOIN
의를 사용하여이었다 좋은 것에서. EXPLAIN EXTENDED
를 붙이는
을 제공합니다
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY customers ref name name 3 const 4334 100.00 Using where; Using temporary; Using filesort
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 7793 100.00
1 PRIMARY <derived3> ALL NULL NULL NULL NULL 8580 100.00 Using where
3 DERIVED customers_addresses index NULL id_customer 5 NULL 8651 100.00
2 DERIVED customers_contacts index NULL id_customer 4 NULL 9314 100.00
내가 어떤 유래 게시물과 MySQL의 문서를 참조하십시오. 둘 다 INNER JOIN
라고 말하는 것이 훨씬 빠릅니다. 나는 UNION ALL
를 사용하여 INNER JOIN
들과 LEFT JOIN
동작을 복제하려고 :
SELECT customers.id_customer,
customers.name,
X.contact AS contact,
Y.street,
Y.zipcode,
Y.city
FROM customers
INNER JOIN
(
SELECT
GROUP_CONCAT(CONCAT(type, ': ', value) SEPARATOR ', ') AS contact,
id_customer
FROM customers_contacts
GROUP BY id_customer
UNION ALL
SELECT
'' AS contact,
id_customer
FROM customers
WHERE id_customer NOT IN (SELECT DISTINCT id_customer FROM customers_contacts)
) AS X
ON X.id_customer = customers.id_customer
INNER JOIN
(
SELECT
GROUP_CONCAT(street SEPARATOR '<br>') AS street,
GROUP_CONCAT(zipcode SEPARATOR '<br>') AS zipcode,
GROUP_CONCAT(city SEPARATOR '<br>') AS city,
id_customer
FROM customers_addresses
GROUP BY id_customer
UNION ALL
SELECT
'' AS street,
'' AS zipcode,
'' AS city,
id_customer
FROM customers
WHERE id_customer NOT IN (SELECT DISTINCT id_customer FROM customers_addresses)
) AS Y
ON Y.id_customer = customers.id_customer
WHERE Y.street LIKE '%Avenue%'
ORDER BY customers.name DESC
LIMIT 0, 20
이 쿼리는 20초하여 성능을 향상시켰다. 그러나 110 초는 여전히 용납되지 않습니다.
EXPLAIN EXTENDED
를 붙이는 :
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 8596 100.00 Using temporary; Using filesort
1 PRIMARY <derived5> ALL NULL NULL NULL NULL 8604 100.00 Using join buffer
1 PRIMARY customers eq_ref PRIMARY,name,name3 PRIMARY 4 Y.id_kunde 1 100.00 Using where
5 DERIVED customers_addresses index NULL id_kunde 5 NULL 8651 100.00
6 UNION customers index NULL name2 767 NULL 8677 100.00 Using where; Using index
7 DEPENDENT SUBQUERY customers_addresses index_subquery id_kunde id_kunde 5 func 2 100.00 Using index
NULL UNION RESULT <union5,6> ALL NULL NULL NULL NULL NULL NULL
2 DERIVED customers_contacts index NULL id_kunde 4 NULL 10411 100.00
3 UNION customers index NULL name2 767 NULL 8677 100.00 Using where; Using index
4 DEPENDENT SUBQUERY customers_contacts index_subquery id_kunde id_kunde 4 func 1 100.00 Using index
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
을 그래서 여기 내 질문 : 어떻게 슈퍼 빠른 응답을 얻기 위해 이러한 쿼리 및/또는 데이터베이스 테이블 중 하나를 개선하기 위해? 나는 솔루션에 관심이있을뿐 아니라 향후 이러한 성능 저하를 방지하는 방법에 대한 전략에도 관심이 있습니다.
감사합니다.
당신이 선택 결과 (하위 쿼리), MySQL이 처음이 하위 쿼리를 실행하는 조인 쿼리를 사용할 때마다, 다음 테이블을 만들 :
"이 쿼리는 130 초 동안"Er, no. 이 쿼리는 구문이 올바르지 않습니다. – Strawberry
죄송합니다. 스택 오버플로에 대한 쿼리를 정리하는 동안 WHERE 부분을 잘못 배치했습니다. 지금 올바른 (테스트 완료) – Timm
'LIKE '% Avenue %''거리가 있어야 할 때'customers_addresses'에'LEFT JOIN'이 필요한 이유는 무엇입니까? –