首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >选择count(*)比选择MySQL中的count(*)慢两倍

选择count(*)比选择MySQL中的count(*)慢两倍
EN

Stack Overflow用户
提问于 2014-11-18 17:04:28
回答 3查看 8.4K关注 0票数 4

我有两个简单的问题:

  1. SELECT count(*) FROM table1 WHERE cond1=exp1 AND cond2=exp2 返回行数。例如47。

  1. SELECT count(*),some_column FROM table1 WHERE cond1=exp1 AND cond2=exp2some_column返回行数(例如47行)和任意值,其速度是第一个查询的两倍!我在服务器上直接测试了它,当然是通过GUI (HeidiSQL)测试的,结果是一样的,查询2的速度是原来的两倍!

知道为什么会这样吗?

我在Win server 2012上使用MySQL服务器5.6.21和Apache/PHP5.3。

更新1:

代码语言:javascript
复制
CREATE TABLE `programs` (
    `tvp_id` INT(11) NOT NULL AUTO_INCREMENT,
    `tvp_time` TIME NOT NULL DEFAULT '00:00:00',
    `tvp_time_end` TIME NOT NULL DEFAULT '00:00:00',
    `tvp_date` DATE NOT NULL DEFAULT '0000-00-00',
    `tvp_title` VARCHAR(200) NOT NULL,
    `tvp_channel` INT(11) NOT NULL DEFAULT '0',
    `tvp_type` VARCHAR(20) NOT NULL,
    `tvp_description` TEXT NOT NULL',

    ... more and more columns ...

    PRIMARY KEY (`tvp_id`),
    INDEX `tvp_date` (`tvp_date`),
    INDEX `tvp_channel` (`tvp_channel`),
    INDEX `tvp_time` (`tvp_time`),
)
ENGINE=MyISAM

我清除缓存并多次运行查询--结果是相同的--查询速度要快2倍。

对我的表的特定查询如下:

代码语言:javascript
复制
1.  SELECT COUNT(*)            FROM programs WHERE (tvp_chanel = value_channel) AND (tvp_date = value_date)

代码语言:javascript
复制
2.  SELECT COUNT(*), tvp_type FROM programs WHERE (tvp_channel = value_channel) AND (tvp_date = value_date)

所以WHERE子句中的两个列都是带有索引的列。

我试着解释一下这个查询:

代码语言:javascript
复制
1. "id" "select_type"   "table" "type"  "possible_keys" "key"   "key_len"   "ref"   "rows"  "Extra"
"1" "SIMPLE"    "programs"  "index_merge"   "tvp_date,tvp_channel"  "tvp_channel,tvp_date"  "4,3"   \N  "15"    "Using intersect(tvp_channel,tvp_date); Using where; Using index"

代码语言:javascript
复制
2. "id" "select_type"   "table" "type"  "possible_keys" "key"   "key_len"   "ref"   "rows"  "Extra"
"1" "SIMPLE"    "programms" "index_merge"   "tvp_date,tvp_channel"  "tvp_channel,tvp_date"  "4,3"   \N  "15"    "Using intersect(tvp_channel,tvp_date); Using where"

不同的是在查询中“使用索引”。那么,为什么查询速度较慢呢?

EN

回答 3

Stack Overflow用户

发布于 2019-10-10 21:06:46

不是直接回答你的问题,但为什么不使用计数(1)而不是计数(*)?正如Patrick所建议的,在优化器选择要依赖的列时可能会出现问题。如果使用count(1),则不涉及任何列,只需对返回的记录数进行计数。

票数 2
EN

Stack Overflow用户

发布于 2014-12-01 02:49:42

这可能是一次黑暗中的尝试,但我可以想象,优化器可能不明智地选择完全扫描非聚集索引(可能是主键),而第二个优化器则以某种方式激励优化器完全扫描聚集索引(AKA,只查看存储的行)。

也可能不是。在任何DBMS中,谁能知道优化器的方式?

票数 0
EN

Stack Overflow用户

发布于 2014-12-01 03:22:59

我注意到你的桌子引擎是myisam,你为什么要用它?无论如何,您是否有可能将其转换为innodb并查看这两个查询发生了什么?

顺便说一句,这可能与您的问题无关,index merge并不总是好的,在某些情况下甚至可能是性能杀手。下面是一个例子:http://www.percona.com/blog/2012/12/14/the-optimization-that-often-isnt-index-merge-intersection/

关键是,许多单列索引可能是一个危险的迹象。例如,如果您的查询是

SELECT COUNT(*) FROM programs WHERE (tvp_chanel = value_channel) AND (tvp_date = value_date)

(tvp_chanel, tvp_date)上的索引是覆盖指数,这是最理想的情况。(是的,我知道这可能是无关紧要的,只是忍不住要提一下)

为了以防万一,在测试时使用select sql_no_cache禁用查询缓存。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26999869

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档