2012-07-09 4 views
1

나는 mysql 테이블을 가지고 있고 "Deactive"상태가 아니고 총합이 0 인 행만 리턴해야한다. (그러나 상태가 비활성 상태 인 행이있을 수있다. 합계는 0이 아니며 반대의 경우도 마찬가지 임).mysql 질의 효율성

SELECT * FROM tableName WHERE uid = id AND (status != "Deactive" OR Total != 0); 

이 바닥 쿼리 많이 걸리는 : 나는 위의 제약 조건을 추가하는 쿼리를 변경할 때 지금 그러나

SELECT * FROM tableName WHERE uid = id; 

:이 요구 사항을 필요로하기 전에 그냥 모든 행을 선택하기 위해 표준 쿼리를하고 있었다 완료하는 데 훨씬 더 길다. 왜 이런 일이 발생하고이 쿼리를 수행 할 수있는 더 나은 방법이 있습니까?

+0

얼마나 많은 레코드를 테이블에 있습니다 당신은 쿼리에 추가 된 필드 중 하나에 인덱스를해야합니까? – Braiba

+0

두 번째 질의는'SELECT * FROM tableName WHERE uid = id AND (status! = "Deactive"OR Total! = 0);'이어야합니다. 또한이 필드에 색인을 추가하면 조회가 더 빨리 실행됩니다 ... –

+0

단지 몇 천 개의 레코드가 있습니다. 그리고 테이블이 그리 크지 않기 때문에 이러한 속성에 대한 인덱스가 없습니다. – ewein

답변

2

첫 번째 쿼리는 인덱스를 기반으로합니다 ('uid'로 가정). 두 번째 쿼리는 다른 값에 대한 필터링입니다. 이 프로그램을 실행, 그리고 당신이 가장을 최적화하는 방법을 알아내는 데 도움이됩니다

EXPLAIN EXTENDED SELECT * FROM tableName WHERE uid = id AND status != "Deactive" OR Total != 0; 

그것은 더러운하지만이 아마 속도를 빠른 방법이 될 것입니다 :

SELECT 
    * 
FROM 
(
    SELECT 
    * 
    FROM 
    tableName 
    WHERE 
    uid = id 
) as temp 
WHERE 
    temp.status != "Deactive" 
    OR temp.Total != 0; 

이 강제 일치하는 uid가있는 행을 먼저 얻은 다음 큰 테이블 스캔을 수행하는 대신 이들을 필터링하는 쿼리. 그래도 전에 말했듯이 EXPLAIN EXTENDED는 친구입니다

+0

Asker가 적절한 괄호를 추가하면 하위 쿼리없이 동일한 성능이 유지 될 것이라고 생각합니다 (MySQL은 매우 빨리 일치하는 행을 삭제합니다). 그것은 (괄호없이), 합계가 평가 될 때까지 행을 제거 할 수 없습니다. OR 조건에 포함될 수 있기 때문입니다. –

-1

각 행의 모든 ​​데이터를 반환해야합니까? 즉 필요한 열만 선택하면 쿼리가 더 빨리 실행됩니다.

또한 "Deactive"상태가 아니고 "0"이 아닌 행을 반환해야한다고 말합니다. 귀하의 질의는 다음과 같아야합니다

SELECT * (or column names) FROM tableName WHERE uid = id AND status != "Deactive" AND Total != 0;

+0

아니요,이 쿼리는 상태가 Deactive이거나 총계가 0 인 모든 행을 제거합니다. 여전히 총계가 0이 아닌 한 Deactive 상태의 행을 원합니다. – ewein