mysql - 选择与 exapain 行不同的计数 (*)

标签 mysql indexing mariadb

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

(EXPLAIN Output Format)

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, where N is the number of rows in the table and S 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/

相关文章:

php - 我该如何查询?

arrays - 对数组进行排序并返回初始索引 VBA

mysql - 哪个索引会加快查询速度?

mysql - 如何在 MySQL 字段中存储正则表达式模式并根据它检查输入?

MYSQL查询查找成对行之间的差异?

php - 使用 Php 将数据插入 mysql 数据库时。我收到错误消息“整数值不正确 : '' for column 'rate' at row 1”

mysql - 为什么这个 SQL INSERT 语句会返回语法错误?

mysql - 使用 mariaDB 将 sql 转储文件安装到 docker 容器

php - 从数据库打印数据到html表

c# - 像按索引访问对象,但在 C# 中按名称访问对象