2011-01-12 7 views
1

이 시나리오는 문제를 명확하게하기 위해 다소 단순화되었습니다. 내 상황에는 MySQL의 데이터 레코드 세트가 관련되어 있습니다.집합 교차 계산을 위해 MySQL GROUP BY/ORDER BY 최적화

CREATE TABLE `records` (           
    `id` bigint(20) NOT NULL,              
    `property1` bigint(20) NOT NULL, 
    `property2` bigint(20) NOT NULL, 
    PRIMARY KEY (`id`), 
    KEY `property1` (`property1`), 
    KEY `property2` (`property2`) 
); 

각 레코드에서 레코드 데이터를 기반으로 다양한 수의 키 (해시)를 생성하고 저장합니다.

CREATE TABLE `rkeys` (
    `rKey` bigint(20) NOT NULL, 
    `rId` bigint(20) NOT NULL, 
    KEY `rKey` (`rKey`), 
    KEY `rId` (`rId`), 
    FOREIGN KEY (`rId`) REFERENCES `records` (`id`) 
); 

은 (키 값은 해시가 더 균등 키 스페이스를 통해이를 배포 할 수 있습니다.)

가있을 수 있습니다, 예를 들어, 500 만 개 기록과 5,000 만 키.

내가하려고하는 것은 키 세트의 퍼지 검색입니다. 가장 공통된 키가있는 데이터베이스의 레코드와 일치시킵니다. 결과는 레코드 테이블의 등록 정보에 대해 필터링해야합니다.

이 같은 외모에서 일한지 쿼리 :

SELECT rkeys.rId, records.property1, SUM(1) as score 
FROM rkeys, records 
WHERE 
    (rKey = 10 OR rKey = 11 OR rKey = 13 OR rKey = 14) AND 
    rkeys.rId = records.id AND 
    records.property1 = 1 AND 
    records.property2 = 2 
GROUP BY rId ORDER BY score DESC; 

성능은 주어진 키 레코드의 수가 매우 작은 경우 괜찮습니다; 문제는 내가 수천 개의 레코드 (5000 개)에 나타나는 키를 누르는 것입니다. 갑자기 GROUP BY/ORDER BY 성능이 절벽에서 떨어졌습니다 (쿼리 당 15-20 초). 키 배포를 부드럽게하는 것은 실제로 옵션이 아닙니다. 레코드 데이터 자체가 고르지 않게 배포됩니다.

레코드 문제에 대한 조인이 문제의 핵심으로 보이지는 않습니다. 단지 컨텍스트에 포함 시켰습니다.

*************************** 1. row *************************** 
      id: 1 
    select_type: SIMPLE 
     table: rkeys 
     type: index 
possible_keys: rKey 
      key: rKey 
     key_len: 8 
      ref: NULL 
     rows: 1 
     Extra: Using where; Using temporary; Using filesort 

내가이 작업을 가속화하기 위해이 테이블이나 쿼리를 재구성 할 수있는 방법이 있나요 :

SELECT rId, SUM(1) as score 
FROM rkeys 
WHERE rKey = 10 OR rKey = 11 OR rKey = 13 OR rKey = 14 
GROUP BY rId ORDER BY score DESC; 

출력을 EXPLAIN : 내가하고 싶은 모든이 경우 나는 여전히 같은 문제를 볼 ?

답변

0

이러한 필드에 클러스터되지 않은 인덱스 (인덱스)를 추가하려고 시도 했습니까? Key가 일부 SQL 엔진에서 수행하는 암시 적 클러스터 된 인덱스 생성을 제외하고는 Keys가 자동으로이 작업을 수행하는 것을 보지 못했습니다.

+0

흠, 나의 이해했다 그 기본이 아닌 인덱스 MySQL이 UNIQUE 인덱스를 클러스터 화하도록 "승격"하거나 행 순서에 따라 합성 인덱스를 생성하지 않는 한 클러스터되지 않았습니다. (http://dev.mysql.com/doc/refman/5.0/en/innodb-index-types.html 참조) – njudge

0

나는 멍청한 놈 해요,하지만

0

SELECT rId, Count(*) as score 
FROM rkeys 
WHERE rKey = 10 OR rKey = 11 OR rKey = 13 OR rKey = 14 
GROUP BY rId ORDER BY score DESC 

같은 시도 (rKey, RID) 또는 (RID, rKey)에 복합 인덱스를 시도하고 테이블

에 인덱스를 추가
(rKey,rId) 

합계를 개수로 바꾸어도 큰 차이가 없어야합니다. (어쨌든 MSSQL에서)

0

"키 값은 더 균등하게 키 공간을 통해 키 값을 분배하기 위해 해시입니다."실제로는 불량입니다. 성능은입니다. 데이터가 너무 커서 캐시 될 수 없으면 임의성에 따라 속도가 느려집니다.

테이블 Keys은 many : many 매핑 테이블과 매우 흡사합니다. Here은 이러한 테이블의 성능을 향상시키기위한 몇 가지 팁입니다.그리고 귀하의 SELECT의 속도를 높일 수 있습니다.

귀하의 SELECT이 '합성'과 '포함하는'인덱스로 크게 개선 될 전망 : MySQL은

INDEX(property1, property2, id) 

(. 최적의 인덱스를 만드는 More tips)