我正在尝试在表上生成新索引以获得最快的查询。 我的 table 叫做“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(*) 获得的总行数?
(添加新信息)
这是来自连接的显示索引
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 的不同值显示在 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
谢谢!
最佳答案
当你运行 EXPLAIN 时,MySQL 不知道有多少行会匹配条件。 rows
列中的数字是统计估计值。
The rows column indicates the number of rows MySQL believes it must examine to execute the query.
For InnoDB tables, this number is an estimate, and may not always be exact.
The average value group size is related to table cardinality, which is the number of value groups. The SHOW INDEX statement displays a cardinality value based on
N/S
, whereN
is the number of rows in the table andS
is the average value group size. That ratio yields an approximate number of value groups in the table.
(InnoDB and MyISAM Index Statistics Collection)
因此,如果您的表有 1000 万行并且 idInstalacion
列包含大约 100 个不同的值,则平均组大小约为 100K。现在一组可能有 50K 行,另一组可能有 150K 行。但同样 - MySQL 在执行查询之前不知道这一点 - 所以它使用平均值。
关于mysql - 选择与 exapain 行不同的计数 (*),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37901848/