提高 MySQL 中的 count() 性能
Posted
技术标签:
【中文标题】提高 MySQL 中的 count() 性能【英文标题】:improving the count() performance in MySQL 【发布时间】:2014-04-27 08:09:40 【问题描述】:我有一个如下所示的 mysql 查询。
SELECT `indexVal`, COUNT(`indexVal`)
FROM `key_word`
WHERE `hashed_word` IN ('001','01v','0ji','0k9','0vc','0@v','0%d','13#' ,'148' ,
'1e1','1sx','1v$','1@c','1?b','1?k','226','2kl','2ue',
'2*l','2?4','36h','3au','3us','4d~')
GROUP BY `indexVal`
此查询需要 5 秒才能生成结果!我什至有一个用ALTER TABLE key_word ADD INDEX (hashed_word, indexVal)
创建的复合索引。请注意,我的查询是计算indexVal
在“搜索”中出现的次数,而不是在“表”中出现的次数。
我的表有 3 列,2800 万条记录,未来的表将有数十亿条记录。我正在使用InndoDB,我刚刚选择了它。下面是我的表格Show Create Table
结果
CREATE TABLE `key_word` (
`primary_key` bigint(20) NOT NULL AUTO_INCREMENT,
`indexVal` int(11) NOT NULL,
`hashed_word` char(3) NOT NULL,
PRIMARY KEY (`primary_key`),
KEY `hashed_word` (`hashed_word`,`indexVal`)
) ENGINE=InnoDB AUTO_INCREMENT=28570982 DEFAULT CHARSET=latin1
我使用Explain
命令运行了上述select
查询。下面是结果
那么我怎样才能加快速度呢?我更喜欢在不到 1 秒的时间内得到结果。感谢您的建议。
PS:我不需要按任何顺序排列结果。
【问题讨论】:
在您之前的问题中,hashed_word IN
出现在哪里,但是在这个问题中出现在 WHERE indexVal
上。现在对于索引,您已经组合了索引,它将始终寻找最左边的前缀并且您有 KEY hashed_word (hashed_word,indexVal)
所以它不采用索引
@AbhikChakraborty:感谢您的关注。我用正确的查询更新了问题。
@AbhikChakraborty:MyIsam
storage 可以帮我吗?
你有很多记录,所以看看如何解决它。
@AbhikChakraborty:谢谢。像 MS SQL Server 这样的付费系统能帮到我吗?
【参考方案1】:
尝试使用反转列顺序的索引:
create index xx on key_word( `indexVal`,`hashed_word`);
这可能有助于防止优化器使用文件排序, 但我不认为这有助于将查询速度从 5 秒加快 500% 到不到 1 秒。 您可能需要更快的硬件。
【讨论】:
那么,我需要删除当前索引吗? 硬件?我的 RAM 是 4GB,你推荐多少 RAM? MS SQL Server 可以帮助我吗? 4GB?您可能应该运行至少 16GB。以及适当的操作系统版本、磁盘类型等。如果您的生产数据库将有数十亿行,那么它将在这种有限的硬件上严重窒息。有关该类型的更多问题,请咨询our DBAs。 5 秒对于几百万行来说听起来不错,即使有索引也是如此。 SQL Server 可能对此有所帮助,但我并不熟悉该方向的相对优点。 SQL Server确实有一些 MySQL 没有的非常很好的特性,这使得一些查询非常容易编写...... @Clockwork-Muse:好的,所以你认为 MSSQL Server 会更快? ...您选择的服务器不太可能成为您当前遇到的问题的限制因素...以上是关于提高 MySQL 中的 count() 性能的主要内容,如果未能解决你的问题,请参考以下文章
提高性能 union all+group by+order by+count