0

我想知道 mysql 视图如何针对 where 子句进行优化。我创建了一个 mysql 视图。

CREATE VIEW `testView` AS
select ID from `table1`
union
select ID from `table2` 

当我触发这个查询时

select * from testView where some_col = 'some_val'

触发此查询后mysql会做什么。

mysql 是否从内存中的 table1 和 table2 中获取所有行,然后触发 where 子句?

或者

直接在内部触发此查询?

select ID from `table1`  where some_col = 'some_val'
union
select ID from `table2`  where some_col = 'some_val' 
4

1 回答 1

0

首先, aVIEW是围绕 a 的语法糖SELECT。那么,让我讨论一下选择:

select ID from `table1`
union
select ID from `table2` 

默认情况下,即UNION DISTINCT,所以会发生这种情况:(UNION ALL会完全不同)

  1. 创建一个包含一列的临时表。
  2. 从表中读取 ID 列;将它们作为行复制到临时表中
  3. 表 2 同上
  4. 删除该临时表的重复数据
  5. 交付行。

为了这:

select * from testView where some_col = 'some_val'

如果没有相关索引,它将读取整个表,检查WHERE子句的每一行。在运行时,它会提供未过滤掉的行(所有列)。

如果它有最佳的INDEX(some_col),它可能会像上面那样做,或者它可能会做:

  1. 进入索引以查找与该WHERE子句匹配的第一行。
  2. 在 B+Tree 中向前扫描,直到子句失败。
  3. 对于每个匹配some_col,传递行。

为了这:

select ID from `table1`  where some_col = 'some_val'
union
select ID from `table2`  where some_col = 'some_val' 

它就像您的第一个UNION,除了每个表可能有也可能没有有用的索引,因此将(或不会)根据您的其他“where”样本进行优化。(至少有 4 种可能的评估方式。)

如果您的最后一件事实际上VIEWVIEW. 解释和拼写变得更加混乱。

使用EXPLAIN ...和/或EXPLAIN FORMAT=JSON ...获取更多信息。(如果您想对输出进行解释,请回来EXPLAIN;它通常有点神秘。

请记住,看似微小的更改可能会对查询的执行方式产生很大的影响。

于 2020-03-02T22:55:34.757 回答