我使用MySQL有以下两个相同的表:
DROP TABLE IF EXISTS `DB`.`tblNew`;
CREATE TABLE `DB`.`tblNew` (
`NumberPK` int(10) unsigned NOT NULL,
`Count` int(10) unsigned NOT NULL,
PRIMARY KEY (`NumberPK`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
和
DROP TABLE IF EXISTS `DB`.`tblPrev`;
CREATE TABLE `DB`.`tblPrev` (
`NumberPK` int(10) unsigned NOT NULL,
`Count` int(10) unsigned NOT NULL,
PRIMARY KEY (`NumberPK`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
我希望在" Count"两个表之间的字段,基于它们加入" NumberPK"字段。
我写了这个查询:
SELECT
gvNew.NumberPK
FROM
tblNew AS gvNew
LEFT OUTER JOIN
tblPrev AS gvPrev ON gvNew.NumberPK = gvPrev.NumberPK
ORDER BY gvNew.Count - IFNULL(gvPrev.Count, 0) DESC
LIMIT 10
为了获得10" NumberPK"记录差异最大的地方。
这个问题是MySql必须执行表扫描以获得Counts的差异。连接是非常有效的,因为它在主键上,虽然有大约50000条记录,结果几乎瞬间返回,我想知道扫描(在每个表中有两个4字节字段的表)是否是与1-4百万行之间的表格一样快。
或者,有没有更好的方法呢?
提前致谢, 添
答案 0 :(得分:0)
在MyISAM中使用PRIMARY KEY
与使用任何其他索引相同:向下钻取索引BTree,然后随机查找数据。
在您的情况下,您需要扫描第一个表的所有行,因为您无法预测哪个行会感兴趣。然后在另一个表中查找每个行,因为再说一次,你无法分辨出需要哪一行。
拥有INDEX(NumberPK, Count)
将避免上述额外步骤。将其添加到两个表中,因为您无法预测优化程序将命中哪些表。 (使用InnoDB,PK的聚类会使该索引变得多余。)
或者......这是另一种可能性。
SELECT NumberPk, MAX(`Count`) - MIN(`Count`) AS diff
FROM (
SELECT * FROM tblNew
UNION ALL
SELECT * FROM tblPrev
) X
GROUP BY NumberPk
ORDER BY diff DESC
LIMIT 10
这摆脱了所有的查找,但增加了很多。所以,我无法预测它是否会更快。