【发布时间】:2013-05-17 06:24:21
【问题描述】:
我对 Views 非常陌生,所以如果这是一个愚蠢的问题,请原谅我,但我有一个 View 对优化相当笨拙的查询非常有帮助,并允许我在然而,我希望 View 会真正存储在某个地方,这样选择它就不会花费很长时间。
我可能弄错了,但我感觉(从create view 的执行速度和我对视图的查询持续时间来看)视图实际上是在外部查询之前作为查询运行的,每个时间我选择反对它。
我真的希望我忽略了一些机制,当我运行 CREATE VIEW 时,它可以完成查询 View 查询 *then 的艰苦工作,这样我随后对该静态视图的选择就会非常迅速。
顺便说一句,我完全理解,显然这个 VIEW 将是创建 VIEW 时存在的数据的快照,并且不会反映在 VIEW 创建之后插入/更新的任何新信息。这实际上正是我所需要的。
TIA
【问题讨论】:
-
所以你想要的是一个物化视图,而不是 mysql 提供的视图,它只是一个巨大查询的别名。从 mysql 5.1 开始,针对视图的 SELECT 查询被缓存,因此任何后续查询都应该很快。究竟是什么东西在这里不适合你?您是否在创建视图的查询中使用子查询?
-
我正在使用一个巨大的查询,在我的 VIEW 中有许多子选择,而且它似乎根本没有缓存。作为概念证明,我简单地调用了
select count(id) from myView,如果 myView 的结果被缓存,我认为它应该非常活泼,但可惜它需要的时间与针对它的任何其他查询一样长。我的视图有子选择的问题吗? (我不确定这是否是子查询的意思,或者是否有区别)。 -
子选择或子查询 - 所以我们在谈论同样的事情。 MySQL 使用自己的查询缓存。比如说,我们有一个 1 百万行的表,你像
select count(*)一样查询它 - 第一次会很慢,第二次会是瞬时的,因为它会提取缓存的数据。相同的规则适用于视图,不同之处在于 MySQL 不缓存子选择结果。这意味着如果您有子选择,您从视图中获得的结果不会被 MySQL 内部缓存。因此,如果您愿意,它将始终从头开始运行查询。这就是为什么您的视图会变慢。 -
您可以做的当然是优化您用于创建视图的查询中涉及的表。视图基本上只是一个别名,因此您不必键入数十个 JOIN 等,这意味着您想要的视图不是物化的。您可以选择从视图中创建一个表并复制该表中的数据(具体化视图),或者您可以优化 MySQL 引擎设置和原始查询。看到没有足够的信息,没有看到查询和索引就无能为力了。
-
不幸的是,视图是一个数据透视表,所以我无法避免子选择(因为它是来自同一个表的几十个子选择,针对特定的 user_ids)。听起来物化是我唯一的选择。我将暂时处理 2 分钟的选择,看看随着时间的推移情况是否会变得更糟。再次感谢您的信息。