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

Mysql解释查询扫描更多行,然后实际返回什么,mysql,Mysql,我使用的是mysql 5.6.22-log 我正在表aggr上执行查询,所有条件都在where子句中 以下是数据 桌子 插入查询 质疑 问题: 上面的查询扫描8行,而根据where条件,它应该只扫描4行 预期结果: 它应该只扫描4行而不是8行 有人能解释为什么mysql扫描8行而不是4行吗 感谢EXPLAIN语句用于获取有关如何执行查询的信息。行数只是一个近似值,查询优化器在构建执行计划时使用它来做出决策。它是数据库管理或开发人员获取诊断信息的工具 EXPLAIN的结果实际上向您显示,查询键为N

我使用的是mysql 5.6.22-log

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

以下是数据

桌子

插入查询

质疑

问题:

上面的查询扫描8行,而根据where条件,它应该只扫描4行 预期结果:

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

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

感谢

EXPLAIN语句用于获取有关如何执行查询的信息。行数只是一个近似值,查询优化器在构建执行计划时使用它来做出决策。它是数据库管理或开发人员获取诊断信息的工具

EXPLAIN的结果实际上向您显示,查询键为NULL时,没有可用的索引。这非常糟糕,可能会导致此查询的速度显著减慢。通过查看您的表定义,我想说您需要一个单独的数据点索引,或者至少尝试使它成为主键的最后一列


然而,这些都不足以解释僵局。我甚至不知道你为什么让我们在这里解释-这与此无关。为了能够诊断死锁,您需要提供更多信息。从表MyISAM、InnoDB等的类型开始,并显示完整的PROCESSLIST。然后,对于每个进程,查看它为每个表持有的锁。

您的问题是死锁。但你会问为什么它扫描8然后返回4。为什么您认为它应该扫描返回的尽可能多的行?上面写着type=ALL。这意味着它会查看所有行。它不使用索引,因为对如此小的表使用索引要慢一些。表中有8行,所以它会查看所有行,根据位置确定需要4行,然后返回这4行。@N.B.表总共有16行。我已经在where子句中指定了唯一键中使用的所有条件。但它扫描8行,而不是4行或16行。大家好,提到有问题的死锁会造成很多混乱,我已经删除了该部分。我的评论仍然有效。没有规则说MySQL将扫描X行并返回X行。@注意,我不是说你错了,但我想问的是,由于上面的查询,如果我在两个不同的会话中使用相同的条件运行delete查询,然后在相同数据的事务锁中删除查询。您可以检查information_Schema.INNODB_LOCKS表以验证lock_数据。
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 ;