Mysql 为什么主键比索引快?

Mysql 为什么主键比索引快?,mysql,optimization,Mysql,Optimization,我有一个MySQL 5.5表,看起来像这样 CREATE TABLE `date_test` ( `id` int(11) NOT NULL DEFAULT '0', `report_date` datetime NOT NULL, `module_id` int(11) NOT NULL, `country_id` int(11) NOT NULL, `clicks` int(11) DEFAULT '0' PRIMARY KEY (`id`,`report_date`

我有一个MySQL 5.5表,看起来像这样

CREATE TABLE `date_test` (
  `id` int(11) NOT NULL DEFAULT '0',
  `report_date` datetime NOT NULL,
  `module_id` int(11) NOT NULL,
  `country_id` int(11) NOT NULL,
  `clicks` int(11) DEFAULT '0'
  PRIMARY KEY (`id`,`report_date`,`module_id`,`country_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
它只有一个PK,没有索引。运行简单的SELECT查询

select count(*) from date_test
where report_date between'2014-09-01' and '2014-09-15'
这需要1.1秒,返回809349条记录

现在,我在report_date上添加了一个索引,以尝试加快速度

ALTER TABLE `date_test`
ADD INDEX `report_date` (`report_date` ASC);
我的选择计数(*)查询现在需要2.6秒才能运行。我的问题;添加此字段作为索引对查询性能有何影响

增加解释

With Index and PK (2.6 seconds) 
id            1   
select_type   SIMPLE    
table         date_test   
type          range   
possible_keys report_date   
key           report_date   
key_len       8   
ref     
rows          792170    
Extra         Using where; Using index    

With PK only, no Index (1.1 seconds)  
id            1   
select_type   SIMPLE    
table         date_test   
type          index   
possible_keys     
key           PRIMARY   
key_len       1048    
ref     
rows          1584341   
Extra         Using where; Using index    

With no Index or PK (1.4 seconds)     
id            1   
select_type   SIMPLE    
table         date_test   
type          ALL   
possible_keys     
key     
key_len     
ref     
rows          1652883   
Extra         Using where   

查看
解释的结果。我的猜测是(没有足够的信息可以确定)MySQL现在正在使用索引,并且错误地猜测使用索引会更快

如果索引覆盖的行比实际的多,只需进行表扫描就可以更快。索引在查询时会增加一些开销,因此如果
之间的
覆盖了表中80%以上的行(完全是任意的,但您知道),那么表扫描会更快

查看此查询的输出以了解以下信息:

SELECT report_date between '2014-09-01' and '2014-09-15', COUNT(*) FROM date_Test
GROUP BY report_date between '2014-09-01' and '2014-09-15'

我已经为三个查询中的每一个添加了解释。我认为你关于MySQL选择“错误”索引的观察在这里适用。为什么你在PK中粘贴了这么多列?尝试检查select count(*)from date_测试,其中报告_日期介于“2014-09-01 00:00:00”和“2014-09-15 23:59:59”之间,以确保不涉及从日期到日期时间的转换。将时间添加到查询似乎不会提高性能,它必须隐式地将“00:00:00”添加到日期。