2009-09-01 4 views
0

,이 쿼리를 개선하는 방법은 무엇입니까? 나는 테이블이

| PAGELETS | CREATE TABLE `PAGELETS` (
    `page_key` int(32) unsigned NOT NULL, 
    `pagelet_serial` int(32) unsigned NOT NULL, 
    `pagelet_shingle` int(32) unsigned NOT NULL 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 

싶습니다하려면 다음에

SELECT * FROM PAGELETS WHERE pagelet_shingle IN(SELECT pagelet_shingle FROM PAGELETS GROUP BY pagelet_shingle HAVING COUNT(DISTINCT page_key) > 1) ORDER BY pagelet_shingle; 

불행하게도,이는 반 정답을 생성하는 쿼리입니다

1) Find all the pagelet_shingles where quantity > 1 (occurs more than once) 
2) out of these only output those that have different page_key 

작은 데이터 세트는 약 18 초가 걸립니다. 내가 다른 쿼리가

,

SELECT dt1.* FROM 
(SELECT * FROM PAGELETS 
GROUP BY page_key, pagelet_shingle HAVING COUNT(*) = 1) 
dt1 JOIN 
(SELECT * FROM PAGELETS GROUP BY pagelet_shingle HAVING COUNT(*) > 1) 
dt2 USING (pagelet_shingle) ORDER BY pagelet_shingle 

기술적으로 정확하지 않은 전문가에 의해 주어진 (뭔가 .. GROUP SELECT * 수 없습니다 당신과 함께 할 수 있습니다)하지만 함께, 빠른 많이 있습니다 결과를 pagelet_shingle가 = 57

+----------+----------------+-----------------+ 
| page_key | pagelet_serial | pagelet_shingle | 
+----------+----------------+-----------------+ 
|  1 |    99 |    57 | 
|  1 |    99 |    57 | 
|  2 |   228 |    57 | 
|  2 |   228 |    57 | 
+----------+----------------+-----------------+ 

은 세미 정확한 질의

,536 생산 PAGELETS FROM 경우

SELECT * 그 결과 집합에서

+----------+----------------+-----------------+ 
| page_key | pagelet_serial | pagelet_shingle | 
+----------+----------------+-----------------+ 
|  1 |    99 |    57 | 
|  1 |    99 |    57 | 
|  2 |   228 |    57 | 
|  2 |   228 |    57 | 
+----------+----------------+-----------------+ 

잘못된 쿼리 pagelet_shingle을 가지고 있지 않지만= 57

내 원하는 결과는

+----------+----------------+-----------------+ 
| page_key | pagelet_serial | pagelet_shingle | 
+----------+----------------+-----------------+ 
|  1 |    99 |    57 | 
|  2 |   228 |    57 | 
+----------+----------------+-----------------+ 

각 한 번만 발생하는 것입니다.

동일한 pagelet_serial에서 두 번 발생하는 pagelet_shingle은 생략됩니다. 부정확 한 2의 속도에 도달하기 위해 csemi orrect 쿼리 속도를하는 방법이 있나요) 1) 나에 대한 잘못된 하나의 문제를 해결하는 방법은 무엇입니까 :

그래서 나는 다음과 같은 묻고 싶다 올바른 것의 결과를 내십시오 (나는 엄격함에 대해 신경 쓰지 않습니다)

+0

모두가, 는 ORDER BY (pagelet_shingle HAVING COUNT (DISTINCT page_key)> 1 BY PAGELETS 그룹에서 선택 pagelet_shingle) PAGELETS WHERE pagelet_shingle IN * FROM DISTINCT SELECT하는 데 도움이 pagelet_shingle; 해결할 수 있지만 어떻게 더 빨리 만들 수 있습니까? –

+0

mysql> EXPLAIN SELECT DISTINCT * pagelet_shingle IN (SELECT pagelet_shingle from pagelet_shingle from pagelet_shingle) pagelet_shingle HAVEING COUNT (DISTINCT page_key)> 1) ORDER BY pagelet_shingle; | 1 | PRIMARY | PAGELETS | 전체 | NULL | NULL | NULL | NULL | 6959 | 사용 장소; 임시 사용; filesort 사용 | | 2 | 부적절한 처분 | PAGELETS | 색인 | NULL | pagelet_shingle | 8 | NULL | 6959 | 인덱스 사용 | –

+0

색인을 추가했습니다. | PAGELETS | 표'PAGELETS'를 CREATE ( 'page_key'의 INT (32) 부호 NULL NOT, 'pagelet_serial'의 INT (32) 부호 NULL NOT, 'pagelet_shingle'의 INT (32) 부호 NULL NOT, KEY'pagelet_shingle' ('pagelet_shingle ') ) ENGINE = MyISAM DEFAULT CHARSET = utf8 | SELECT DISTINCT * 여기에서 PAGELETS 위치 pagelet_shingle IN (SELECT pagelet_shingle PAGELETS GROUP BY pagelet_shingle HAVEING COUNT (DISTINCT page_key)) 1) ORDER BY pagelet_shingle; 은 여전히 ​​지옥처럼 느립니다. –

답변

0

SELECT DISTINCT p.* ...과 같은 소리가 선택 될 것입니다.

P. 그리고 두 번째 것을 정말 추천합니다! 모든 것을 느리게 만들어야하며 (주의를 기울인 것처럼) 필요할 때만 사용해야합니다.

+0

실제로 느린 경우 두 번째 것을 권하고 싶습니다. 나는 이것이 현재 크기의 20 배가 넘는 데이터 세트에 적용될 것이므로 두 번째 것을 사용하고 싶지 않습니다. SELECT DISTINCT * 여기에서 PAGELETS 위치 pagelet_shingle IN (SELECT pagelet_shingle FROM PAGELETS GROUP BY pagelet_shingle HAVEING COUNT (DISTINCT page_key)) 1) ORDER BY pagelet_shingle; 해결할 수 있지만 인덱스를 사용하여 속도를 향상시키는 방법은 무엇입니까? (나는이 문제에 대해 어느 색인을해야하는지 모르지만 색인 키 (page_shingle, page_key)를 시도했지만 똑같이 느리다. –

+0

처음에는 조금 일찍 시작했다. 물론 첫 번째를 의미했다. –

0

이 쿼리로 문제가 해결되지 않았습니까?

SELECT dt1.* FROM 
(SELECT DISTINCT * FROM PAGELETS 
GROUP BY page_key, pagelet_shingle HAVING COUNT(*) = 1) 
dt1 JOIN 
(SELECT * FROM PAGELETS GROUP BY pagelet_shingle HAVING COUNT(*) > 1) 
dt2 USING (pagelet_shingle) GROUP BY pagelet_shingle 
+0

아니 -하지의 MySQL은 (참조 : ENGINE =의 MyISAM) – goddva

+0

(1,64,8) (1,64,9) (1,64,10) (1,64,11) (1,64 12) (1,64,13) (1,64,14) (1,64,15) (1,64,16) (1,41,20) (1,41,21) (1,41,22) (1,99,48) (1,99,49) (1,99,50) (1,99,51) (1,99,52) (1,99,53) (1,99,54) (1,99,58) (1,99,59) (1,99,60) (1,99,61) 실제로 실제로는 다른 page_key 값을 가진 것은 볼 수 없습니다. page_key = 57 문제가 여전히 존재하는 경우 (두 번 이상 발생하기 때문에 결과 집합 안에 없습니다) –

0

SELECT * FROM PAGELETS GROUP BY pagelet_serial, pagelet_shingle HAVING COUNT(*) > 0 

당신을 제공 무엇입니까?

+0

| page_key | pagelet_serial | pagelet_shingle | + ---------- + ---------------- + ----------------- + | 1 | 56 | 1 | | 1 | 56 | 2 | | 1 | 56 | 3 | | 2 | 186 | 8 | | 1 | 64 | 8 | | 1 | 64 | 9 | | 2 | 186 | 9 | | 1 | 64 | 10 | | 2 | 186 | 10 | –

+0

은 정말 원하지 무엇을 : (1,56,1) (1,56,2) (1,56,3) (2,186,8) (1,64,8) (1,64 9) (2,186,9) (1,64,10) (2,186,10) (1,64,11) (2,186,11) (1,64,12) (2,186,12 (2,186,15) ) (1,64,13) (2,186,13) (1,64,14) (2,186,14) (1,64,15) (1,64,16) (2,186,16) (1,41,20),(2,203,20) (1,41,21) (2,203,21) (2,203,22) (1,41,22) (1,21,27) (1,21,28) (1,21,33) (1,21,34) (1,21,29) (1,21,30) (1,21,31) (1,21,32) (1,21,35) (1,21,36) (1,21,37) (1,21,38) (1,21,39) (1,21,40) (1, 21,41) (1,21,42) (1,21,43) (1,21,44) (2,228,48),(1,99,48) (2,228,49) (1,99,49) (2,228,50) (1,99,50) (2,228,51) (1,99,51) (2,228,52) (1,99,52) –

0

은 GROUP BY 및 HAVING을 사용합니다.

SELECT * 
    FROM `pagelets` 
GROUP BY `pagelet_shingle` 
    HAVING COUNT(*) > 1 

추가로 당신은 MySQL의에서 내가 무엇을 읽고으로 판단

0

(SQL 표준과 다른) 그런 식으로 작업을해야하지만 자기가 출력에 모든 열을 가입 할 수있는, 당신을 위해 무엇을 찾고있는 것입니다 :

SELECT DISTINCT p1.page_key, p1.pagelet_serial, p1.pagelet_shingle 
    FROM PAGELETS p1 
    JOIN PAGELETS p2 ON p2.page_key   = p1.page_key 
        AND p2.pagelet_serial = p1.pagelet_serial 
        AND p2.pagelet_shingle <> p1.pagelet_shingle 

그 쿼리는 (page_key, pagelet_serial)에 인덱스의 전체를 사용 할 것 초,하지 초 열 번째에 완료해야합니다.

귀하가 찾고자하는 것이 아니었다면, 귀하의 테이블에있는 값이 (1,2,3), (1,2,3), (1, 1,3,0), (1,2,3), (1,1,3), (1,2,4), (1,1,4), (1,1,4)

관련 문제