2009-09-01 9 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秒かかります。

私は別のクエリ、(あなたと一緒に何かを* ..グループを選択することはできません)技術的に正しいではなくて、LOT高速化された結果を生成し、専門家によって与えられた

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 

を持っていますpagelet_shingle = 57

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

半正しいクエリが

を生成するページレットからケース

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で2回発生するpagelet_shingleは省略されます。間違った1 2の速度に到達するためにcsemi orrectクエリをスピードアップするための方法があります) 1)またはそれに間違ったものを修正する方法があります:

だから私は、次お願いしたいと思います正しい結果を出す(私は厳密さを気にしない)

+0

みんなを助け、IN pagelet_shingleは、ORDER BY(COUNT(DISTINCT page_key)> 1 HAVING pagelet_shingle BYレットグループからpagelet_shingleを選択)ページレット* FROM DISTINCT SELECT :このうち

チェックpagelet_shingle; これを解決しますが、どうすれば速くすることができますか? –

+0

mysql> EXPLAIN SELECT DISTINCT *ここからpagelet_shingle IN(SELECT 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 | 'page_key' int(32)unsigned NOT NULL、 ' pagelet_serial' int(32)unsigned NOT NULL、 'pagelet_shingle' int(32)unsigned NOT NULL、 KEY' pagelet_shingle'( 'pagelet_shingle ') )ENGINE = MyISAM DEFAULT CHARSET = utf8 | SELECT DISTINCT * pagelet_shingle where(pagelet_shingleからページンググループへ)pagelet_shingle HAVEING COUNT(DISTINCT page_key)> 1)ORDER BY pagelet_shingle; はまだ地獄のように遅いです –

答えて

0

SELECT DISTINCT p.* ...のようなサウンドがあなたの選択になります。

P.S.そして私は本当に2番目をお勧めします!あなたは気がついたようにすべてを遅くして、必要な場所でのみ使うべきです。

+0

実際に遅い場合は、なぜ2番目のものをお勧めしますか? 2番目のデータセットを使用したくないのは、現在のサイズの20倍を超えるデータセットに適用されるためです。 ここから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

Nope - MySQL以外(Ref: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 (0120)(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,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では、それは(SQL標準とは異なる)そのように動作しなければならないのに、更にあなたは、自己が出力するすべての列に参加行うことができます

0

、あなたが探していることは次のとおりです。

クエリが (page_key, pagelet_serial)にインデックスをフルに活用するだろうし、秒、ない秒の第十に完了する必要があり
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 

これがあなたが探していたものでない場合は、テーブルの値が(1,2,3)、(1,2,3)、(1、 (1,3,4)、(1,2,4)、(1,1,4)、(1,1,4)