提高 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() 性能的主要内容,如果未能解决你的问题,请参考以下文章

使用 SUM 时提高 MySQL 查询性能

提高性能 union all+group by+order by+count

MySQL count(*) 性能优化

mongodb - count 提高性能

提高MSSQL数据库性能对比count(*) 和 替代count(*)

SQL 提高性能