2014-07-09 2 views
2

왜이 두 쿼리는 동일한 ORDER BY가있을 때 다른 결과 집합을 반환합니까?MySQL INNER 대 LEFT JOIN 다른 순서

처음으로 사용자가 INNER JOIN 인 경우 쿼리의 차이는 약 5 초입니다. 두 번째로 LEFT JOIN을 사용했으며 0.05 초가 걸렸습니다. 두 경우 모두 정확히 43.000 행을 반환하지만 tck.id 순서가 다르므로 왜 또는 어떤 방법으로 결과를 얻을 수 있습니까?

SELECT tck.*, acc.ac_name 
FROM support_tickets tck 
INNER JOIN support_ticket_accounts acc USING (id_support_ticket_account) 
WHERE tck.id_company = 2 AND tck.st_status = 1 ORDER BY tck.st_priority DESC 

편집 :

SELECT tck.*, acc.ac_name 
FROM support_tickets tck 
    LEFT JOIN support_ticket_accounts acc ON tck.id_support_ticket_account = acc.id_support_ticket_account 
WHERE tck.id_company = 2 AND tck.st_status = 1 
ORDER BY tck.st_priority DESC; 
+----+-------------+-------+--------+---------------+------------+---------+-------------------------------+-------+-----------------------------+ 
| id | select_type | table | type | possible_keys | key  | key_len | ref       | rows | Extra      | 
+----+-------------+-------+--------+---------------+------------+---------+-------------------------------+-------+-----------------------------+ 
| 1 | SIMPLE  | tck | ref | id_company | id_company | 5  | const       | 37586 | Using where; Using filesort | 
| 1 | SIMPLE  | acc | eq_ref | PRIMARY  | PRIMARY | 4  | tck.id_support_ticket_account |  1 |        | 
+----+-------------+-------+--------+---------------+------------+---------+-------------------------------+-------+-----------------------------+ 

SELECT tck.*, acc.ac_name 
FROM support_tickets tck 
    INNER JOIN support_ticket_accounts acc ON tck.id_support_ticket_account = acc.id_support_ticket_account 
WHERE tck.id_company = 2 AND tck.st_status = 1 
ORDER BY tck.st_priority DESC; 
+----+-------------+-------+------+-------------------------------------+----------------------------+---------+-------------------------------+------+---------------------------------+ 
| id | select_type | table | type | possible_keys      | key      | key_len | ref       | rows | Extra       | 
+----+-------------+-------+------+--------------------------------------+---------------------------+---------+-------------------------------+------+---------------------------------+ 
| 1 | SIMPLE  | acc | ALL | PRIMARY        | NULL      | NULL | NULL       | 5 | Using temporary; Using filesort | 
| 1 | SIMPLE  | tck | ref | id_company,id_support_ticket_account | id_support_ticket_account | 5  | acc.id_support_ticket_account | 2085 | Using where      | 
+----+-------------+-------+------+--------------------------------------+---------------------------+---------+-------------------------------+------+---------------------------------+ 
+0

왼쪽 아무것도없는 곳에와 결합하지만 같은 내부는 시간이 쿼리 캐시 될 수 우려가까지로, 가입 동작합니다. 먼저 왼쪽 조인을 사용한 다음 내부 조인을 사용하고 시간을 봅니다. –

+0

두 쿼리 모두에 대해'EXPLAIN'의 출력을 제공 할 수 있습니까? – Vyktor

+0

@AbhikChakraborty 'acc'에 WHERE 조건이 없습니다. – Strawberry

답변

1

방금 ​​ORDER BY tck.st_priority DESC 여러 다른 레코드를 추적 할 수없는 가망하고 모두 각각의 경우에 대해 반환 할 수있는 경우 (왼쪽 또는 내부). 그 이유는 동일한 st_priority을 가진 많은 레코드를 가져야하기 때문입니다. 따라서 그 중 아무 것도 특별한 순서없이 올 수 있습니다.
레코드를 고유 한 가능한 위치에 제공하기 위해 order by 절에 필드를 더 추가하면 두 레코드 모두에서 동일한 순서를 갖게됩니다 querys.

1

나는 지연에 대한 책임이 있다고 생각한다. (단 하나의 질문에는 왜 필요한 것이지 다른 질문에는 필요하지 않다.). 나는 multi-column index가 도움이 만들 생각 :

CREATE INDEX filter 
    ON support_tickets(id_company, st_status, st_priority) 
    USING BTREE;