2012-02-22 2 views
5

MySQL 서버 버전 : 우분투 10.04MySQL의 조회수 또는 IN 절 대

에 5.1.41 내가 어떤 쿼리를 수정할 때의 MySQL의 행동에 차이를 가로 질러 와서 그것에 대한 이유를 알고 싶어.

기본적으로보기를 만듭니다. 뷰를 쿼리 할 때 결과 집합은 동일합니다 그러나 읽는 행의 수는 OR 절보다 IN 절의 내용이 다릅니다.

CREATE TABLE country ( 
    id_country int(11) NOT NULL AUTO_INCREMENT, 
    name varchar(50) NOT NULL, 
    PRIMARY KEY (id_country) 
) ENGINE=InnoDB; 

INSERT INTO country (name) VALUES ('A'), ('B'), ('C'), ('D'), ('E'), ('F'), ('G'), ('H'); 

CREATE TABLE status ( 
    id_status int(11) NOT NULL AUTO_INCREMENT, 
    id_country int(11) NOT NULL, 
    status tinyint(4) NOT NULL, 
    PRIMARY KEY (id_status) 
) ENGINE=InnoDB; 
ALTER TABLE status ADD INDEX (id_country); 
ALTER TABLE status ADD FOREIGN KEY (id_country) REFERENCES test.country (id_country) ON DELETE RESTRICT ON UPDATE RESTRICT ; 

INSERT INTO status(id_country, status) VALUES 
(1,0), (2,1), (3,0), (4,1), (5,0),(6,1), (7,0), (8,1); 

CREATE ALGORITHM=MERGE VIEW view_country 
AS 
    SELECT c.*, s.id_status, s.status 
    FROM country c JOIN status s ON c.id_country = s.id_country; 

2 개의 행의 표시 다른 수 아래 문을 설명 당신은 "행을 볼 경우 또는 제

mysql> EXPLAIN EXTENDED SELECT * FROM view_country WHERE id_country = 1 OR id_country = 2 OR id_country = 3\G; 
*************************** 1. row *************************** 
      id: 1 
    select_type: SIMPLE 
     table: s 
     type: ALL 
possible_keys: id_country 
      key: NULL 
     key_len: NULL 
      ref: NULL 
     rows: 8 
    filtered: 37.50 
     Extra: Using where 
*************************** 2. row *************************** 
      id: 1 
    select_type: SIMPLE 
     table: c 
     type: eq_ref 
possible_keys: PRIMARY 
      key: PRIMARY 
     key_len: 4 
      ref: test.s.id_country 
     rows: 1 
    filtered: 100.00 
     Extra: 
2 rows in set, 1 warning (0.00 sec) 

를 사용

mysql> EXPLAIN EXTENDED SELECT * FROM view_country WHERE id_country IN (1, 2, 3)\G; 
*************************** 1. row *************************** 
      id: 1 
    select_type: SIMPLE 
     table: c 
     type: range 
possible_keys: PRIMARY 
      key: PRIMARY 
     key_len: 4 
      ref: NULL 
     rows: 3 
    filtered: 100.00 
     Extra: Using where 
*************************** 2. row *************************** 
      id: 1 
    select_type: SIMPLE 
     table: s 
     type: ref 
possible_keys: id_country 
      key: id_country 
     key_len: 4 
      ref: test.c.id_country 
     rows: 1 
    filtered: 100.00 
     Extra: 
2 rows in set, 1 warning (0.00 sec) 

을 구문 분석 : 아래의 아래의 간단한 예입니다 "두 쿼리 모두 - 서로 다르게 합쳐집니다.

쿼리는 OR 절은 IN에 비해 적은 행을 읽습니다.이 테이블은 거대한 테이블과 조인을 합산합니다.

이유가 무엇인지 이해할 수 있습니까?

감사합니다.

+0

지속적으로 동일하지만 서로 다른 결과 : 연구 성과와 실행에

더 다음 두 사이트를 체크 아웃 계획? –

+0

@Marcus - 나는 혼란 스럽다. 질문을 이해하지 못했다. 매번 일관성있는 결과를 얻었고, 매번 해석되는 행의 수가 일정하다는 것을 의미한다면, 대답은 예이다. – naveen

+0

@Marcus Adams - 복사 붙여 넣기가있다. 내 부분에 큰 실수 - 나는 그것을 정정했다. 이 문제는 다른 결과 집합에 대한 것이 아닙니다. 결과 집합은 동일하지만 읽는 행 수는 IN과 OR 사이에 다릅니다. 재현 할 수없는 경우 알려주십시오. - 서버 버전 : 5.1 – naveen

답변

1

그 실행 계획이 인덱스의 상태와 테이블의 크기와는 많이 있습니다 참고 : 나는 질문이 하나의 가능한 중복 생각 그렇다면,보다

. MySQL은 유사한 쿼리에 대해서도 다르게 실행될 수 있으며 때로는 MySQL이 잘못 판단 할 수도 있습니다.

JOIN을 사용한보기가 분명히 복잡하므로 SELECT 문이 간단하지 않습니다. MySQL이 IN 대 OR에 대해 다른 실행 계획을 선택한다는 것에 놀라지 마십시오.

첫 번째 쿼리의 경우 MySQL은 두 쿼리에 대해 인덱스를 사용하기 때문에 EXPLAIN에 특정 행 수가 정확합니다.

그러나 두 번째 쿼리에서 MySQL은 상태 테이블의 모든 행을 검색하도록 선택했습니다. 행이 너무 적기 때문에 MySQL은 테이블을 방문해야하므로 필요한 모든 행을 반환하는 커버 인덱스가 없기 때문에 의미가 있습니다. 두 번째 쿼리가 실제로 첫 번째 쿼리보다 빠르지 않은 경우 놀랄 일이 아닙니다. 또한 EXPLAIN의 행 수 (예상치)는 예상치이므로 쿼리를 프로파일 링 할 때 고려해야합니다.

첫 번째 쿼리는 6 개의 룩업을 수행해야하지만 두 번째 쿼리는 매우 짧은 테이블 스캔 이후에만 3 개의 룩업을 수행하면됩니다.

MySQL이 수행하는 많은 트릭은 현재 인덱스와 행 수를 기반으로 쿼리를 최적화하려고하는 매우 특정한 시나리오로 제한되는 경우가 있습니다. 문서화 된 경우는 for similar queries, MySQL will take two different approaches and end up with the same execution path입니다. 두 가지 완전히 다른 실행 계획이 비슷한 성능을 보이는 다른 경우가 있는데,이 경우 중 하나입니다.

어쨌든, 이것이 차이점이 무엇인지 설명해 주시길 바랍니다. 그러나 결과가 같고 성능이 비슷하면 걱정할 것이 없습니다.

앞에서 말했던 것처럼 MySQL은 최상의 추측을하지 못하고 인덱스 힌트와 자연스러운 조인과 같은 도구를 사용할 수 있습니다. 귀하의 경우에는 MySQL이 올바르게 작동하고 있다고 생각합니다.

+0

설명에 감사드립니다. Marcus - 좋은 연습으로 복잡한 결합 쿼리를 수행하고 mysql이 인덱스를 선택하는 방법을 알아야한다고 생각합니다. – naveen

0

내가 제대로 이해한다면 얻는 결과는 같고 속도와 작동 방식에 대한 'OR'과 'IN'절의 차이점을 알고 싶습니다. IN vs OR in the SQL WHERE Clause

+0

나는 OP가 "OR"과 반대로 "IN"을 사용하여 결과가 다르다고 답했다. –

+0

아, 그럼 그의 질문을 제대로 이해하지 못했습니다. 나는 결과가 같을 것이라고 생각했을 것이다. – Honnes

+0

@ZackMacomber, 질문 : * "결과 집합이 동일합니다"*. –