我正在尝试在表上生成新索引以获得最快的查询。 我的桌子名为'conexiones':
CREATE TABLE `conexiones` (
`idConexion` int(10) unsigned NOT NULL AUTO_INCREMENT,
`idInstalacion` int(10) unsigned DEFAULT NULL,
`idUsuario` int(11) DEFAULT NULL,
`tMacAdres` varchar(64) DEFAULT NULL,
`tUsuario` varchar(128) DEFAULT NULL,
`tNombre` varchar(64) DEFAULT NULL,
`tApellido` varchar(64) DEFAULT NULL,
`tEmail` varchar(64) DEFAULT NULL,
`tSexo` varchar(20) DEFAULT NULL,
`fNacimiento` date DEFAULT NULL,
`nAmigos` int(11) DEFAULT NULL,
`tPoblacion` varchar(64) DEFAULT NULL,
`fFecha` datetime DEFAULT NULL,
`tEvento` varchar(20) DEFAULT NULL,
PRIMARY KEY (`idConexion`),
KEY `idInstalacion` (`idInstalacion`),
KEY `tMacAdress` (`tMacAdres`) USING BTREE,
KEY `fFecha` (`fFecha`),
KEY `idUsuario` (`idUsuario`),
KEY `insta_fecha` (`idInstalacion`,`fFecha`)
) ENGINE=InnoDB AUTO_INCREMENT=2365270 DEFAULT CHARSET=utf8;
该表有2365270行。
我不理解的是运行该查询:
select count(*) from conexiones
where conexiones.idInstalacion=190
返回值为:59314
但如果我插入EXPLAIN表,则返回:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE conexiones ref idInstalacion,insta_fecha idInstalacion 5 const 108830 "Using index"
108830行?
为什么搜索的行数多于我从count(*)得到的总行数?
(添加新信息)
这是来自connexions的展示索引
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
conexiones 0 PRIMARY 1 idConexion A 2304649 NULL NULL BTREE
conexiones 1 idInstalacion 1 idInstalacion A 2658 NULL NULL YES BTREE
conexiones 1 tMacAdress 1 tMacAdres A 2304649 NULL NULL YES BTREE
conexiones 1 fFecha 1 fFecha A 2304649 NULL NULL YES BTREE
conexiones 1 idUsuario 1 idUsuario A 2304649 NULL NULL YES BTREE
conexiones 1 insta_fecha 1 idInstalacion A 1422 NULL NULL YES BTREE
conexiones 1 insta_fecha 2 fFecha A 2304649 NULL NULL YES BTREE
idInstalacion不同值显示为arround 1000
表conexiones有2.365.270行。
最后,当不在内存上时,查询变慢,第一次15秒,第二次2秒或0,6秒,是:
select count(distinct(concat(conexiones.tMacAdres,date_format(conexiones.fFecha,'%Y%m%d')))) as Conexiones,
sum(if(conexiones.tEvento='megusta',1,0)) as MeGusta,sum(if(conexiones.tEvento='megusta',conexiones.nAmigos,0)) as ImpactosMeGusta,
sum(if(conexiones.tEvento='checkin',1,0)) as CheckIn,sum(if(conexiones.tEvento='checkin',conexiones.nAmigos,0)) as ImpactosCheckIn,
min(conexiones.fFecha) Fecha_Inicio, now() Fecha_fin,datediff(now(),min(conexiones.fFecha)) as dias
from conexiones, instalaciones
where conexiones.idInstalacion=instalaciones.idInstalacion and conexiones.idInstalacion=190
and (fFecha between '2014-01-01 00:00:00' and '2016-06-18 23:59:59')
group by instalaciones.tNombre
order by instalaciones.idCliente
谢谢!
答案 0 :(得分:3)
当您运行EXPLAIN时,MySQL并不知道有多少行符合条件。 rows
列中的数字是统计估算值。
行列表示MySQL认为必须的行数 检查以执行查询。
对于 InnoDB 表,此数字是估算值,可能并非总是如此 精确。
平均值组大小与表基数有关,即 值组的数量。 SHOW INDEX语句显示一个 基于
N/S
的基数值,其中N
是行中的行数 table和S
是平均值组大小。这个比率产生了一个 表中的近似值组数。
(InnoDB and MyISAM Index Statistics Collection)
因此,如果您的表格有10M行且idInstalacion
列包含大约100个不同的值,则平均组大小约为100K。现在一个组可能有50K行,另一个组有150K行。但是再一次 - MySQL在执行查询之前并不知道 - 所以它使用了平均值。