Mysql参数化视图

问题描述 投票:0回答:1

我想知道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子句?

OR

直接在内部触发此查询?

select ID from `table1`  where some_col = 'some_val'
union
select ID from `table2`  where some_col = 'some_val' 
mysql view mariadb
1个回答
0
投票

首先,VIEWSELECT周围的语法糖。因此,让我讨论选择:

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种可能的评估方法。)

如果您的最后一件事实际上是VIEW的主体,则最优化器是否选择“物化”内容,然后进行过滤,或者将调用者的内容与VIEW“合并”,这会增加复杂性。这甚至更使人难以解释和说明。

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

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

© www.soinside.com 2019 - 2024. All rights reserved.