视图如何在 DBM 中工作?
Posted
技术标签:
【中文标题】视图如何在 DBM 中工作?【英文标题】:How do Views work in a DBM? 【发布时间】:2009-01-09 14:14:54 【问题描述】:假设我有两个这样的表:
雇主(id、name、....、deptId)。 部门(id,部门名称,...)。但是这些数据不会经常修改,我想要这样的查询
SELECT name, deptName FROM Employers, Depts
WHERE deptId = Depts.id AND Employers.id="ID"
尽可能快。
我想到了两种可能的解决方案:
对表格进行非规范化:
尽管使用此解决方案,我将失去“标准化数据库”的一些巨大优势,但这里的性能是必须的。
为该非规范化数据创建一个视图。
我将保持数据规范化并且(这是我的问题),在该视图上的查询性能将比没有该视图时更快。
或者问同样问题的另一种方式,每次对视图进行查询时都会“解释”视图,或者视图在 DBA 中是如何工作的?
【问题讨论】:
【参考方案1】:一般来说,除非您“物化”视图,这是某些软件(如 MS SQL Server)中的一个选项,否则视图只会转换为针对基表的查询,因此不会比原始视图快或慢(减去翻译查询所需的时间非常短,与实际执行查询相比微不足道)。
你怎么知道你有性能问题?您是否在负载下对其进行分析?你验证过性能瓶颈是这两张表吗?一般来说,在你得到硬数据之前,不要假设你知道性能问题来自哪里,也不要花时间优化,直到你知道你正在优化正确的东西 - 80% 的性能问题来自 20 % 的代码。
【讨论】:
是的。实际上,在大多数情况下,我同意您的看法,这通常不是性能问题。但在这种情况下,它就成了(你可以想象,上面的例子并不是真正的问题)。我正在寻找一种方法来“实现”该视图(如您所说),但在 mysql 中。有什么想法吗?【参考方案2】:如果 Depts.ID 是该表的主键,并且您索引 Employers.DeptID 字段,那么即使超过数百万条记录,此查询也应该保持非常快。
在那种情况下,非规范化对我来说没有意义。
一般来说,视图的性能与运行查询本身时的性能几乎完全相同。视图的优点是简单地将查询抽象出来,因此您不必考虑它。
您可以使用物化视图(或有人说的“快照”),但您的数据只会与上次刷新时一样新。
【讨论】:
我认为你不需要在employees.deptId 上建立索引,甚至——只需要在两个表的主键上。无论如何,“where”子句将强制您在employees.id 上使用表扫描或主索引;完成后,返回 deptId 索引会适得其反,因此不会被使用。 @kogus 那个场景只是大问题的一部分,这里的重点是数据将是静态的,所以在这个场景中,规范化给你的优势并不是真正需要的。我想有一个没有连接表的查询的性能(好像Depts的数据在Employers)【参考方案3】:在对其中一个回复的评论中,问题的作者解释说他正在寻找一种在 MySQL 中创建物化视图的方法。
MySQL 不像其他 DBMS 那样将物化视图的概念封装在一个适合您的包中,但它确实拥有创建一个所需的所有工具。
你需要做的是:
-
创建查询结果的初始具体化。
在将与新插入的雇主匹配的所有行插入到具体化表中的雇主表中插入时创建触发器。
在雇主表中创建删除触发器,从具体化表中删除相应的行。
在雇主表中创建更新触发器,以更新具体化表中的相应行。
departments 表也是如此。
如果您的基础表不经常更新,这可能会正常工作;但是一旦你这样做了,你需要知道创建/更新/删除操作的额外成本。 此外,您还需要确保一些不了解您的诡计的 DBA 在时机成熟时不会在不迁移触发器的情况下迁移数据库。所以好好记录吧。
【讨论】:
是的,这将是一个很好的解决方案,感谢您的解释。我赞成您的回答(以及其他人),我很乐意将其标记为正确,但老实说我最初的问题,Ian Varley 的回答似乎是合适的(对此真的很抱歉)。非常感谢。【参考方案4】:听起来像是过早的优化,除非您知道这是一个明确且存在的问题。
MySQL 不实现视图,它们并不比对基表的查询快。此外,在某些情况下,它们的速度较慢,因为它们的优化不太好。
但是视图也会“隐藏”一些东西,让开发人员在未来维护代码,让他们想象查询没有实际复杂。
【讨论】:
以上是关于视图如何在 DBM 中工作?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 swiftui 中弹出到 TabView 应用程序中的特定视图。我也使用了 StackNavigation 但不在 swiftui 中工作
如何让 scrollViewDidScrollToTop 在 UITableView 中工作?
如何初始化自定义视图(控制器),以便它以编程方式和在 Interface Builder 中工作?
如何让 View.invalidate 在 Click Listener 中工作