选择与exapain行不同的count(*)

时间:2016-06-18 21:34:47

标签: mysql indexing mariadb

我正在尝试在表上生成新索引以获得最快的查询。 我的桌子名为'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

谢谢!

1 个答案:

答案 0 :(得分:3)

当您运行EXPLAIN时,MySQL并不知道有多少行符合条件。 rows列中的数字是统计估算值。

  

列表示MySQL认为必须的行数   检查以执行查询。

     

对于 InnoDB 表,此数字是估算值,可能并非总是如此   精确。

(EXPLAIN Output Format)

  

平均值组大小与表基数有关,即   值组的数量。 SHOW INDEX语句显示一个   基于 N/S 的基数值,其中 N 是行中的行数   table和 S 是平均值组大小。这个比率产生了一个   表中的近似值组数。

(InnoDB and MyISAM Index Statistics Collection)

因此,如果您的表格有10M行且idInstalacion列包含大约100个不同的值,则平均组大小约为100K。现在一个组可能有50K行,另一个组有150K行。但是再一次 - MySQL在执行查询之前并不知道 - 所以它使用了平均值。