Mysql 如何改进此查询?

Mysql 如何改进此查询?,mysql,Mysql,我有一张桌子 | 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 我想: 1) Find all the pagelet_shing

我有一张桌子

| 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 
我想:

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
这是生成半正确答案的查询:

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;
不幸的是,在一个小数据集上大约需要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),但产生的结果要快得多,在以下情况下:

从pagelet_shingle=57的pagelet中选择*

+----------+----------------+-----------------+
| page_key | pagelet_serial | pagelet_shingle |
+----------+----------------+-----------------+
|        1 |             99 |              57 | 
|        1 |             99 |              57 | 
|        2 |            228 |              57 | 
|        2 |            228 |              57 | 
+----------+----------------+-----------------+
半正确的查询生成

+----------+----------------+-----------------+
| page_key | pagelet_serial | pagelet_shingle |
+----------+----------------+-----------------+
|        1 |             99 |              57 | 
|        1 |             99 |              57 | 
|        2 |            228 |              57 | 
|        2 |            228 |              57 | 
+----------+----------------+-----------------+ 
而不正确的查询在其结果集中没有pagelt_shingle=57

我期望的结果是

+----------+----------------+-----------------+
| page_key | pagelet_serial | pagelet_shingle |
+----------+----------------+-----------------+
|        1 |             99 |              57 |  
|        2 |            228 |              57 | 
+----------+----------------+-----------------+ 
每次只发生一次

在同一pagelet_序列中出现两次的pagelet_木瓦将被忽略

因此,我想问以下问题: 1) 有没有办法加快csemi orrect查询的速度以达到错误查询的速度
2) 或者有没有一种方法可以修复不正确的错误以产生正确的结果(我不在乎严格程度)

听起来像是
选择不同的p.*。
将是您的选择


p.S.我真的推荐第二个!让一切都变慢(就像你刚才注意到的那样),并且应该只在必要的时候使用。

这个查询不是解决了你的问题吗

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
什么是

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

给你?

使用分组和拥有,例如

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

此外,您还可以进行自连接以输出所有列,尽管在mysql中它应该是这样工作的(与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
选择不同的p1.page\u键、p1.pagelet\u序列、p1.pagelet\u木瓦
来自PAGELETS p1
在p2.page\u key=p1.page\u key上连接小页面p2
p2.pagelet_serial=p1.pagelet_serial
和p2.小木瓦p1.小木瓦
该查询将充分利用
(page\u key,pagelet\u serial)
上的索引,并应在十分之一秒(而不是几秒)内完成


如果这不是您想要的,请告诉我们,如果表中的值是:(1,2,3),(1,2,3),(1,1,3),(1,1,3),(1,2,4),(1,2,4),(1,2,4),(1,1,4),(1,1,4),(1,1,4),您是否尝试过使用
exists
而不是
中的

看看这个:


希望这对MySQL没有帮助(参考:ENGINE=MyISAM)(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,61)实际上,我看不到任何具有不同page_键值的内容;page_key=57问题仍然存在的问题(在结果集中找不到,因为它发生了多次)|页码|小页|小页|小页|小页|小页|小页|小页|小页|小页|小页|小页|小页|小页|小页|小页|小页|小页|小页|小页|小页|小页|小页|小页|小页|小页|+--------------------不是我真正想要的:(1,56,1)(1,56,2)(1,56,3)(2186,8)(1,64,8)(1,64,9)(2186,9)(1,64,10)(2186,10)(1,64,11)(2186,11)(1,64,12)(2186,12)(1,64,13)(2,186,13) (1,64,14) (2,186,14) (1,64,15) (2,186,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,29) (1,21,30) (1,21,31) (1,21,32) (1,21,33) (1,21,34) (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)(2228,50)(1,99,50)(2228,51)(1,99,51)(2228,52)(1,99,52)实际上,如果第二个速度慢,为什么要推荐第二个呢?我不想使用第二个,因为这将应用于超过其当前大小20倍的数据集。选择DISTINCT*FROM pagelet,其中pagelet_shingle在其中(从PAGELETS组中选择pagelet_shingle,按pagelet_shingle的计数(不同的page_键)>1)按pagelet_shingle的顺序;解决了这个问题,但有没有办法使用索引来加速这个问题?(我不知道应该为这个问题索引哪个,我尝试了索引键(page_shingle,page_键)但它同样缓慢,对我来说有点太早了。当然我指的是第一个。每个人,从pagelet中选择DISTINCT*FROM pagelet WHERE pagelet_shingle IN(从pagelet GROUP中选择pagelet_shingle BY pagelet_shingle have COUNT(DISTINCT page_key)>1)按pagelet_shingle排序;解决了这个问题,但我现在如何让它更快?mysql>解释从pagelet_shingle所在的pagelet中选择DISTINCT*(按pagelet组中具有计数的pagelet_shingle(DISTINCT page_key)>1选择pagelet_shingle)按pagelet|u shingle;| 1 | PRIMARY | pagelet | ALL | NULL | NULL | NULL | NULL | 6959 |使用where;使用临时;使用文件排序| 2 |依赖子查询| pagelet |索引| NULL | pagelet | u shingle | 8 | NULL | 6959 |使用索引|我添加了一个索引,| PAGELETS |创建表
PAGELETS
page_-key
int(32)无符号非空,
pagelet_-serial
int(32)无符号非空,
pagelet_-shingle
pagelet_-shingle
)ENGINE=MyISAM DEFAULT CHARSET=utf8 |从pagelet中选择DISTINCT*,其中pagelet_shingle IN(按pagelet组按pagelet_shingle的计数(DISTINCT page_key)>1选择pagelet_shingle)按pagelet_shingle排序;仍然非常慢