代码之家  ›  专栏  ›  技术社区  ›  Alpesh Jikadra

Mysql explain查询扫描更多行,然后实际返回什么

  •  0
  • Alpesh Jikadra  · 技术社区  · 7 年前

    我正在使用mysql 5.6.22日志

    我正在表aggr上执行查询,所有条件都在where子句中。

    以下是数据

    桌子

    CREATE TABLE aggr (
     a_date DATE,
     product_id INT(11),
     data_point VARCHAR(16),
     los INT(11),
     hour_0 DOUBLE(4,2),
     UNIQUE KEY `unique_row` (a_date,product_id,data_point,los),
     INDEX product_id(product_id)
    );
    

    插入查询

    INSERT INTO aggr(a_date,product_id,data_point,los,hour_0) 
    VALUES
    ('2018-07-29',1,'arrivals',1,10),('2018-07-29',1,'departure',1,9),
    ('2018-07-29',1,'solds',1,12),('2018-07-29',1,'revenue',1,45.20),
    ('2018-07-30',1,'arrivals',2,10),('2018-07-30',1,'departure',2,9),
    ('2018-07-30',1,'solds',2,12),('2018-07-30',1,'revenue',2,45.20),
    
    ('2018-07-29',2,'arrivals',1,10),('2018-07-29',2,'departure',1,9),
    ('2018-07-29',2,'solds',1,12),('2018-07-29',2,'revenue',1,45.20),
    ('2018-07-30',2,'arrivals',2,10),('2018-07-30',2,'departure',2,9),
    ('2018-07-30',2,'solds',2,12),('2018-07-30',2,'revenue',2,45.20);
    

    查询

    EXPLAIN 
    SELECT * FROM aggr
    WHERE a_date BETWEEN '2018-07-29' AND '2018-07-29' 
    AND product_id = 1 
    AND data_point IN('arrivals','departure' ,'solds','revenue') 
    AND los = 1 ;
    

    问题

    1. 上面的查询扫描8行(而根据where条件,应该只扫描4行)

    enter image description here

    预期结果:

    它应该只扫描4行而不是8行。

    有人能解释为什么mysql扫描8行而不是4行吗?

    谢谢

    1 回复  |  直到 7 年前
        1
  •  1
  •   jurez    7 年前

    EXPLAIN 语句用于获取有关如何执行查询的信息。这个 rows 数字是 仅逼近 ,查询优化器在生成执行计划时用于作出决策。它是由数据库管理或开发人员获取诊断信息的工具。

    结果是什么 解释 实际上是显示您没有可用于查询的索引( key (NULL) ). 这非常糟糕,可能会导致此查询显著减速。通过查看表定义,我可以说您需要一个单独的索引 data_point ,或者至少尝试使其成为主键的最后一列。

    然而,这些都不足以解释僵局。我都不知道你为什么要给我们看 解释 这里-这和它无关。为了能够诊断死锁,您需要获取更多信息。从你的桌子类型开始( MyISAM , InnoDB 等)和 SHOW FULL PROCESSLIST . 然后,对于每个进程,查看它为每个表保留的锁。