2013-09-04 2 views
1

, 우리는 30M + 행 InnoDB의 테이블 다음 한 필요 (인덱싱 문제)보다 더 많은 행을 찾는 : participant_id + question_id + given_answer_id이 고유MySQL의 우리의 MySQL 5.5 데이터베이스에서

+----------------+-------------+-----------------+--------+ 
| participant_id | question_id | given_answer_id | status | 
+----------------+-------------+-----------------+--------+ 
|  500  |  12  |  25  | 0 | 
+----------------+-------------+-----------------+--------+ 

조합.

PRIMARY KEY (이 순서대로)

KEY INDEX

를 given_answer_id question_id
  • participant_id : 순간

    우리는 다음 키이 모든 participant_id 사이가

    [...] WHERE participant_id = x AND question_id = y AND given_answer_id = z; 
    

    [...] WHERE question_id = x; 
    

    일반적으로 :

    • , 우리는 선택 쿼리의 이가지 우리의 응용 프로그램이이 테이블

    을 question_id 0 및 < 다른 줄이있는 100 개의 행 tion_ids. 다른 방법으로, 모든 question_id는 participant_ids가 서로 다른 행을 무제한 (일반적으로 100,000 개 이상) 가질 수 있습니다. 첫 번째 쿼리는 두 번째 쿼리보다 자주 실행됩니다. 반면

    EXPLAIN SELECT * FROM example WHERE question_id = 500; 
    
    +----+-------------+-----------+------+---------------+-------------+---------+-------+-------+-------+ 
    | id | select_type | table  | type | possible_keys | key   | key_len | ref | rows | Extra | 
    +----+-------------+-----------+------+---------------+-------------+---------+-------+-------+-------+ 
    | 1 | SIMPLE  | example | ref | question_id | question_id | 8  | const | 32096 |  | 
    +----+-------------+-----------+------+---------------+-------------+---------+-------+-------+-------+ 
    

    , 우리는하지 않고 동일한 쿼리 를 실행할 경우에만 18732 행이을 반환 내용 설명 : 우리는 쿼리를 다음 실행할 때

    , 그것은 고개를 32,096 행이 있음을 보여줍니다.

    이 오버 헤드를 방지하기 위해이 테이블에서 필요한 인덱스는 무엇입니까?


    여기이 테이블 생성하는 코드입니다 : 권장하는 나는, dba.stackexchange.com이 질문을 게시 한

     
    CREATE TABLE `example` (
        `participant_id` BIGINT(20) UNSIGNED NOT NULL, 
        `question_id` BIGINT(20) UNSIGNED NOT NULL, 
        `given_answer_id` BIGINT(20) UNSIGNED NOT NULL, 
        `status` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0', 
        PRIMARY KEY (`participant_id`, `question_id`, `given_answer_id`), 
        INDEX `question_id` (`question_id`) 
    ) 
    ENGINE=InnoDB; 
    
  • +0

    더 나은 시도 이 질문을 http://dba.stackexchange.com/ – Hackerman

    +0

    으로 이동하십시오. 32096은 단지 예상치 일뿐입니다. question_id에 색인이 있고 "="를 사용하는 경우 "색인 전용"으로 이동하지 않으면 훨씬 더 잘할 수 없습니다. 즉 두 번째 색인을 (question_id, participant_id, given_answer_id, status)로 만듭니다. 그렇게하면 DBMS는 인덱스를 읽어야하고 기본 테이블로 이동하지 않습니다. 그러나 3 천만 행을 사용하면 큰 색인을 원하지 않을 수 있습니다. –

    답변