正常选择比计数更快(*)

时间:2013-04-09 09:45:36

标签: mysql select count innodb myisam

我想做这样的计数(作为一个例子,不是真的算狗):

SELECT COUNT(*)
FROM dogs AS d INNER JOIN races AS r ON d.race_id = r.race_id
    LEFT INNER colors AS c ON c.color_id = r.color_id
WHERE d.deceased = 'N'

我在MyISAM桌上有130,000只狗。 Races有1,500条记录,是一个9列的InnoDB表,颜色有83条记录,也是InnoDB,有两列(id,name)。 * _id列都是主键,我在'外键'上有索引dogs.race_id和races.color_id,我有一个关于dogs.deceased的索引。所提到的列都不能是NULL

# mysql --version
mysql  Ver 14.12 Distrib 5.0.51a, for debian-linux-gnu (i486) using readline 5.2

现在的问题是:在我的PhpMyAdmin中,此查询需要1.8秒(使用SQL_NO_CACHE),计数结果为64,315。将COUNT(*)更改为COUNT(d.dog_id)COUNT(d.deceased)也会使查询运行1.8秒,结果相同。

但是当我删除COUNT()并且只执行SELECT *SELECT dog_id时,运行大约需要0.004秒(然后使用类似mysql_num_rows()的内容计算结果)

这怎么可能?如何让COUNT()更快地完成工作?

修改:在EXPLAIN下面添加了

EXPLAIN SELECT COUNT(*)
FROM dogs AS d INNER JOIN races AS r ON d.race_id = r.race_id
    INNER JOIN colors AS c ON c.color_id = r.color_id
WHERE d.deceased = 'N'

给我:

+----+-------------+-------+-------+------------------+----------+---------+----------------------+------+-------------+
| id | select_type | table | type  | possible_keys    | key      | key_len | ref                  | rows | Extra       |
+----+-------------+-------+-------+------------------+----------+---------+----------------------+------+-------------+
|  1 | SIMPLE      | c     | index | color_id         | color_id | 4       | NULL                 |   83 | Using index | 
|  1 | SIMPLE      | r     | ref   | PRIMARY,color_id | color_id | 4       | database.c.color_id  |   14 | Using index | 
|  1 | SIMPLE      | d     | ref   | race_id,deceased | race_id  | 4       | database.r.race_id   |  123 | Using where | 
+----+-------------+-------+-------+------------------+----------+---------+----------------------+------+-------------+

3 个答案:

答案 0 :(得分:1)

MySQL Optimizer仅在需要时执行全表扫描,因为列可以为NULL,这意味着如果列未定义为NOT NULL,则可能会有一些NULL值,因此MySQL必须执行表扫描找出。如果您的列d.dog_id可以为空?尝试在另一个不可为空的列上运行计数,这应该为您提供比count(*)更好的性能。

答案 1 :(得分:0)

尝试在dogs.deceased上设置索引并使用SELECT COUNT(*) ... USE INDEX my_index_name

答案 2 :(得分:0)

创建索引以加快计算速度:

CREATE INDEX ix_temp ON dogs (d.race_id)
INCLUDE (columns needed for the query)