MySQL解释查询扫描更多行然后实际返回什么

时间:2018-07-30 16:53:21

标签: mysql

我正在使用mysql 5.6.22-log

我正在对表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 个答案:

答案 0 :(得分:1)

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

EXPLAIN的结果实际上显示给您的是您的查询没有可用的索引(key(NULL))。这非常糟糕,并且可能导致此查询的速度显着下降。通过查看表定义,我想说的是,您需要为data_point使用单独的索引,或者至少尝试使其成为主键的最后一列。

但是,这还不足以解释僵局。我什至不知道您为什么在这里向我们展示EXPLAIN-与它无关。为了能够诊断死锁,您需要提供更多信息。从表的类型(MyISAMInnoDB等)和SHOW FULL PROCESSLIST开始。然后,对于每个进程,查看每个表持有什么锁。