我想知道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是否从内存中的表1和表2中获取所有行,然后激发where子句?
或
直接在内部激发此查询?
select ID from `table1` where some_col = 'some_val'
union
select ID from `table2` where some_col = 'some_val'
首先,VIEW
是围绕SELECT
的语法糖。所以,让我讨论一下选择:
select ID from `table1`
union
select ID from `table2`
默认情况下,这是UNION DISTINCT
,所以会发生以下情况:(UNION ALL
会非常不同(
- 创建一个包含一列的临时表
- 从表中读取ID列;将它们全部作为行复制到临时表中
- 表2同上
- 对临时表进行重复数据消除
- 交付行
为此:
select * from testView where some_col = 'some_val'
如果没有相关的索引,它将读取整个表,检查每一行的WHERE
子句。在运行时,它会传递未筛选出的行(所有列(。
如果它有最佳INDEX(some_col)
,它可以如上所述,也可以这样做:
- 进入索引,查找与
WHERE
子句匹配的第一行 - 在B+树中向前扫描,直到子句失败
- 对于每个匹配的
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
的输出,请回来;它通常有点神秘。
请记住,看似微小的更改可能会对查询的执行方式产生重大影响。