【问题标题】:Mysql - "EXPLAIN SELECT" from a VIEW is looking in all rows of the main tableMysql - 来自 VIEW 的“EXPLAIN SELECT”正在查看主表的所有行
【发布时间】:2023-03-19 13:21:01
【问题描述】:

我有 2 张桌子:

  • t_cities (idCity, idCountry, name, population)
  • t_countries (idCountry, name)

t_cities 有 50000 行,所以我创建了一个包含英国城市的视图(只有 1100 个):

CREATE VIEW v_city_uk AS SELECT * FROM t_cities WHERE idCountry = 140

到目前为止一切都很好,我得到了一个包含 1100 行的 VIEW。
查询

SELECT COUNT(*) FROM v_city_uk

返回 1100,但解释:

EXPLAIN SELECT COUNT(*) FROM v_city_uk

表示它正在检查 50000 行以执行此查询。为什么?
有没有办法让这不会发生?因为我创建视图是为了加快查询速度而不是相同的。


编辑:我需要一个“聚合表”,感谢 matthewdavidson。

【问题讨论】:

  • 你的表有索引吗?我的第一个猜测是视图仍然需要执行 select 和 where 子句,因此它仍然需要确定您要查找的子集。
  • (idCountry)上添加索引。

标签: mysql sql views


【解决方案1】:

因为视图不是预编译查询或存储结果,它是预定义查询。它在视图中执行 SELECT 语句,每次。否则,视图将永远不会更新。视图是查询的表示。它对程序员来说是一种方便的简写,但对机器来说却不是。

换句话说,当你

SELECT something FROM YourView

YourView 是由

定义的
CREATE VIEW YourView AS SELECT stuff FROM sometable 
INNER JOIN othertable ON sometable.column = othertable.column

实际运行的是

 SELECT something FROM 
(SELECT stuff FROM sometable 
INNER JOIN othertable ON sometable.column = othertable.column)

如果要存储结果,则应使用聚合表。

【讨论】:

  • 感谢 Matthew,但是(来自 dev.mysql.com/doc/refman/5.0/en/create-view.html): - 视图定义在创建时被“冻结”,因此之后对基础表的更改不会影响视图定义。例如,如果视图在表上定义为 SELECT *,则稍后添加到表中的新列不会成为视图的一部分。所以我认为它就像一个“永久”_temporary_table
  • 但是“聚合表”就是答案,f*那个观点,非常感谢马修
  • 不是定义是否改变,而是结果集是否改变。每次查询时,视图都会使用它所使用的查询重新创建自己。
猜你喜欢
  • 1970-01-01
  • 2014-12-25
  • 2021-11-16
  • 2015-01-22
  • 1970-01-01
  • 1970-01-01
  • 2016-05-15
  • 2012-06-28
  • 1970-01-01
相关资源
最近更新 更多