我想知道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'
首先,VIEW
是SELECT
周围的语法糖。因此,让我讨论选择:
select ID from `table1`
union
select ID from `table2`
默认情况下为UNION DISTINCT
,所以会发生这种情况:(UNION ALL
会大不相同)
为此:
select * from testView where some_col = 'some_val'
如果没有相关索引,它将读取整个表,并检查WHERE
子句的每一行。运行时,它会交付未过滤掉的行(所有列)。
如果具有最佳的INDEX(some_col)
,则可以执行上述操作,或者可以执行以下操作:
WHERE
子句匹配的第一行。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
输出,请回来;它通常有点神秘。
请记住,看似很小的更改可能会对执行查询的方式产生很大的影响。