2009-09-24 3 views
1

나는 datetime (DATE) 및 bit (PUBLIC) 테이블이 있습니다. 이제filesort를 사용하여 MySQL의 datetime 열 정렬

내가 1 그래서 내가 사용 = DATE에 의해 PUBLIC와 함께 주문 행을 싶습니다 :

select 
    c.* 
from 
    Cars c 
WHERE 
    c.PUBLIC = 1 
ORDER BY 
    DATE DESC 

을하지만 불행하게도 나는이 가지고에 무슨 일이 일어나고 있는지보고 설명 사용할 때 :

1 SIMPLE a ALL  IDX_PUBLIC,DATE  NULL NULL NULL 103  Using where; Using filesort 

그리고 나는 단지 100 개의 행을 가지고있는 동안이 데이터를 가져 오는 데 0.3 밀리 초가 걸립니다. filesort를 비활성화하는 다른 방법이 있습니까?

내가 색인에 간다면 나는 색인 (PUBLIC, DATE)이 고유하지 않습니다.

테이블 정의 : 당신이 날짜를 기준으로 주문하는 경우

CREATE TABLE IF NOT EXISTS `Cars` (
    `ID` int(11) NOT NULL auto_increment, 
    `DATE` datetime NOT NULL, 
    `PUBLIC` binary(1) NOT NULL default '0' 
    PRIMARY KEY (`ID`), 
    KEY `IDX_PUBLIC` (`PUBLIC`), 
    KEY `DATE` (`PUBLIC`,`DATE`) 
) ENGINE=MyISAM AUTO_INCREMENT=186 ; 
+0

테이블의 정의를 게시 하시겠습니까? 'SHOW CREATE TABLE Cars'를 실행하십시오. – Quassnoi

+0

@Quassnoi - Ok. 100 행에 대해 –

+0

300 마이크로 초를 추가 했습니까? 행당 3 마이크로 초? 그 성능은 썩지 않습니다. –

답변

1

당신은 public 및 종류에 date에 필터링합니다 (public, date)

이 방법 MySQL에 복합 인덱스가 있어야합니다.

EXPLAIN에서 (public, date)에 복합 색인이없는 것을 확인했습니다.

대신 publicdate에 서로 다른 두 개의 인덱스가 있습니다. 적어도, 그게 그들의 이름은 IDX_PUBLICDATE입니다.

업데이트 :

당신 public 열이 BIT 아니다, 그것은 BINARY(1)입니다. 문자 유형이며 문자 비교를 사용합니다.

정수와 문자를 비교할 때 MySQL은 후자를 전자로 변환합니다. 반대의 경우도 마찬가지입니다.난,

SELECT c.* 
FROM Cars c 
WHERE c.PUBLIC = '1' 
ORDER BY 
     DATE DESC 

:

CREATE TABLE t_binary (val BINARY(2) NOT NULL); 

INSERT 
INTO t_binary 
VALUES 
(1), 
(2), 
(3), 
(10); 

SELECT * 
FROM t_binary 
WHERE val <= 10; 

--- 
1 
2 
3 
10 

SELECT * 
FROM t_binary 
WHERE val <= '10'; 
--- 
1 
10 

중 하나가 bit 수 또는이 같은 쿼리를 다시 작성하기 위해 public 열을 변경

이 쿼리는 다른 결과를 반환합니다. 이자형. 정수가 아닌 문자와 문자를 비교합니다.

+0

하나의 색인이 (PUBLIC)에 있고 두 번째 색인이 복합 (PUBLIC, DATE)입니다. 나는 첫번째 것을 제거해야합니까? –

+0

두 번째 것은 어쨌든 사용해야합니다. 표의 정의를 게시 해주십시오. – Quassnoi

+0

문제 없습니다. 탭 def를 추가했습니다. –

1

, 정렬이 필요합니다. 날짜별로 색인이 없으면 파일 x 호가 사용됩니다. 그것을 제거하는 유일한 방법은 날짜에 색인을 추가하거나 순서를 수행하지 않는 것입니다.

또한 filesort가 항상 파일이 디스크에 정렬된다는 것을 의미하지는 않습니다. 테이블이 충분히 작거나 정렬 버퍼가 충분히 크면 메모리에서이를 정렬 할 수 있습니다. 테이블 자체를 정렬해야한다는 것을 의미합니다.

인덱스에 이미 날짜가 있고 where 절에 PUBLIC을 사용하고 있기 때문에 MySQL은 해당 인덱스를 사용할 수 있어야합니다. 그러나 옵티마이 저는 인덱스가 너무 적어 인덱스를 귀찮게하지 않을 것임을 결정했을 수 있습니다. 테이블에 10,000 개 정도의 행을 추가하고 다시 분석하여 계획 변경 여부를 확인하십시오.