【问题标题】:Select count(*) different from exapain rows选择与 exapain 行不同的 count(*)
【发布时间】:2016-10-20 11:43:53
【问题描述】:

我正在尝试在表上生成新索引以获得最快的查询。 我的表叫做“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 行。

最后,当不在内存中时,查询变慢,第一次是 15s,第二次是 2s 或 0,6s,是:

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 indexing mariadb


【解决方案1】:

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

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

对于 InnoDB 表,这个数字是一个估计值,可能并不总是 准确的。

(EXPLAIN Output Format)

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

(InnoDB and MyISAM Index Statistics Collection)

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

【讨论】:

  • 根据官方参考:“rows 列表示 MySQL 认为它必须检查以执行查询的行数。对于 InnoDB 表,这个数字是估计值,可能并不总是准确的。 " Source
  • @OscarJofre,idInstalacion 的基数是多少?运行show index from conexiones。该表中的总行数是多少?
  • @OscarJofre,2658 的基数似乎无法解释 EXPLAIN 输出中的数字 (108830)。我预计会达到 1000 (2365270/2658)。 MySQL 似乎使用了其他一些统计数据。
  • “100”也是近似的——通过对 BTree 进行少量“潜水”。底线:不要相信解释数字。然而,它们“通常”会导致执行查询的最佳方式。 5.8 中可能会有所改进。
猜你喜欢
  • 1970-01-01
  • 2011-09-15
  • 1970-01-01
  • 2016-06-26
  • 1970-01-01
  • 1970-01-01
  • 2017-02-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多