2010-08-19 2 views
3
SELECT count(*) c FROM full_view WHERE verified > (DATE (NOW()) - INTERVAL 30 DAY) 

쿼리를 실행하면 분할 초가 걸리지 만 비교 연산자를 전환하면 주변에 많은 시간이 걸립니다. 이제 첫 번째 방법은 count = 0이고 두 번째 방법은 count = 120000이지만, 단지 마이크로 초가 걸린 전체 테이블을 계산하면됩니다.MySQL - COUNT는 "보다 큼"이 빠르지 만 "미만"은 영원히 걸리는 이유는 무엇입니까?

하지만 쿼리가 끝나면 이후에 매우 빠르게 실행되기 때문에 펑키 한 무언가가 있습니다. MySQL은 쿼리 또는 뭔가를 캐싱하고 있습니까? 음, 웹 사이트가 멈추지 않도록 캐시에 의존하고 싶지 않습니다.

이 말은 무의미한 것처럼 보입니다. 특정 날짜보다 빠르게 모든 항목을 계산할 수 있다면 왜 그 반대 수를 계산하는 데 더 오래 걸릴까요? 어느 쪽이든 전체 테이블을 살펴 봐야합니까? 반환해야 할 모든 것이 숫자이므로 대역폭이 문제가되지 않아야합니다.

쿼리에 대한 설명 :

1, 'SIMPLE', 'b', 'range', 'updated,verified_index', 'updated', '3', '', 28, 'Using where'`  
1, 'SIMPLE', 'l', 'eq_ref', 'PRIMARY', 'PRIMARY', '4', 'xyz_main.b.loc_id', 1, 'Using index' 
1, 'SIMPLE', 'f', 'ALL', '', '', '', '', 2214, '' 

편집 :

Handler_read_rnd_next :

나는 쿼리를 실행할 때

이 어떤 관심이있을 수 있습니다, 나는이 정보를 발견

  • 254436689 (whe N 이하

Key_read_requests)보다 대

  • 2()보다 하 : 314,393 (33 대 33은 사용 통계 모두 최대 수가 크다)

    Handler_read_key보다 : 104,303 vs 1

    보기를 바이 패스하고 주 테이블에서 직접 쿼리를 실행하면 느려질 필요가 없습니다. 속도를 높이려면 어떻게해야합니까? 뷰는 다음과 같이 본질적 :이 해결

    SELECT x, y, z, verified FROM table1 LEFT JOIN table2 on tab2_ID = table2.ID LEFT JOIN table3 on tab3_ID = table3.ID 
    

    : 프랭키가 올바른 방향으로 내을했다. 두 번째로 조인 된 테이블 (회사 테이블)은 회사의 전체 텍스트 이름을 통해 조인되었습니다. 나는 최근에 그 테이블에 정수 키를 추가하기로 결정했습니다. 이름 열은 색인이 생성되어야한다고 생각 했었지만 나는 그것을 망쳤습니다. 어쨌든 나는 모든 것을 재구성했다. 주 테이블의 외래 키를 전체 회사 이름이 아닌 회사 테이블의 정수 ID와 일치하도록 변환했습니다. 각 테이블의 해당 열을 다시 인덱싱 한 다음 새 조인 포인트를 반영하도록 뷰를 업데이트했습니다. 이제는 양방향으로 즉시 실행됩니다. :) 그래서 정수형 키가 핵심이라고 생각합니다. 문제는 사라졌지만 여전히 원래 질문이 실제로 해결 된 것 같지 않습니다.

    도움 주셔서 감사합니다.

  • +0

    'full_view'는보기라고 가정합니다. 그 정의는 무엇입니까? –

    +1

    '계획 설명'에서 무엇을 말합니까? –

    +0

    full_view에는 확인 된 열이있는 주 테이블이 두 개의 다른 테이블에 조인 된 채로 남아 있습니다. 기본 테이블은 사람들이고 다른 두 테이블은 위치와 회사 정보를 결합합니다. 그것은 꽤 똑 바른 앞으로입니다. – Moss

    답변

    3

    아래의 쿼리를 실행하고 결과를 게시하십시오.

    EXPLAIN SELECT count(*) c 
    FROM full_view 
    WHERE verified > (DATE (NOW()) - INTERVAL 30 DAY) 
    

    긴 거의 항상 뭔가를 제공 EXPLAIN를 잊어! ;)


    편집 1 :
    이 아마 공격 라인 :

    1, 'SIMPLE', 'f', 'ALL', '', '', '', '', 2214, '' 
    

    전체 테이블 스캔이 있음이 내용의 ALL.

    Explain syntax on this diagram을 더 파고들 수 있습니다.
    This doc will sure make things much clearer on the Explain output. Please check it out.


    편집 : 3 :
    단계별 분석가


    편집 2 ... 차이가 어디로 볼을 시도 할 Explain 명령의.

    1, 'SIMPLE', 'b', 'range', 'updated,verified_index', 'updated', '3', '', 28, 'Using where'`  
    1 - id 
    SIMPLE - simple select, not using sub-queries 
    b - table name 
    range - only rows that are in a given range are retrieved, using an index 
    updated,verified_index - are both possible keys 
    updated - was the key eventually used 
    3 - key lenght 
    '' - this is the ref column and would show which columns or constants are compared to the index name in the key column to select rows from the table. 
    28 - number of rows mysql believes it must examine to execute the query 
    Using where - self explanatory 
    
    2

    제 생각 엔 Date(Now())의 뺄셈은 처리하는 데 시간이 많이 걸리는 것 같습니다. verified의 값이 이미 Date(Now())보다 작 으면 그 시점에서 ("보다 큼"을 비교할 때) 거짓이어야하므로 평가가 단락 될 수 있습니다.

    "미만"과 비교하는 경우 현재 시간에 관계없이 모든 경우에서 날짜 시간을 빼야합니다. 이전에 논리적으로 표현식을 논리적으로 결론 지을 방법이 없으므로 날짜 시간 빼기를 계산

    그것은 단지 추측이지만, 소금 한 알씩 가져 가라.

    +0

    명시적인 날짜 사용은 또한 오래 걸립니다. – Moss

    +0

    @Moss 흥미로운, 어쩌면 내 생각은 오프베이스입니다. 비교 순서를 뒤집는 것은 어떻습니까? 'A < B', do 'B > A' 대신에 오랜 시간이 걸리는지 확인하십시오. 정확히 같은 것을 실행해야합니다. (내가 추측 할 것입니다.) –

    +0

    흥미로운 생각이지만, 지금은 시도하기에는 너무 늦었습니다. betters 키/인덱싱 문제를 해결했습니다. – Moss

    0

    테이블에 verified의 색인이있는 경우보다 제한적인 (> 1)이 더 빠릅니다. WHERE 절이없는 COUNT (*)는 테이블/인덱스 통계에서 계수를 수집 할 수 있으므로 신속하게 리턴 할 수 있습니다.

    +0

    카운트 내에 비교를 넣는 것은 더 나은 구문이지만 속도를 향상 시키지는 못합니다. 그리고 나는 '검증 된'것에 대한 색인을 가지고있다. – Moss

    +0

    사실이 방법을 사용하면 두 방향 모두에서 속도가 느려집니다. – Moss

    1

    데이터베이스 엔진에 30 일 넘게 검증 된 레코드가 없다는 통계가있을 수 있습니다. 이 경우 테이블을 읽지 않아도 통계 히스토그램에서 정보를 얻을 수 있습니다.

    관련 문제