假设我有两个表:
Employers (id, name, .... , deptId). Depts(id, deptName, ...).
但是这些数据不会经常修改,我希望像这样的查询
SELECT name, deptName FROM Employers, Depts
WHERE deptId = Depts.id AND Employers.id="ID"
尽可能快。
我的脑子里有两种可能的解决方案:
对表格进行非规范化:
尽管有了这个解决方案,我将失去一些“规范化数据库的巨大优势,但这里的性能是必须的。
为该非规范化数据创建一个视图。
我会保持数据规范化并且(这是我的问题),如果没有该视图,查询在该视图上的性能会更快。
或者提出同样问题的另一种方式是,每次对它进行查询时,View都会被“解释”,或者如何在DBA中使用视图Stuff?。
答案 0 :(得分:5)
通常情况下,除非您“实现”视图,这是某些软件(如MS SQL Server)中的一个选项,否则视图只会转换为针对基表的查询,因此不会比原始视图更快或更慢(减去翻译查询所花费的时间非常少,与实际执行查询相比没什么用。)
你怎么知道你有性能问题?你在负载下分析它吗?您是否验证了性能瓶颈是这两个表?通常,在您获得硬数据之前,不要假设您知道性能问题的来源,并且在您知道正在优化正确的事情之前不要花费任何时间进行优化 - 80%的性能问题来自20代码的百分比。
答案 1 :(得分:1)
如果Depts.ID是该表的主键,并且您将Employers.DeptID字段编入索引,那么即使在数百万条记录上,此查询仍应保持非常快。
在那种情况下,反规范对我来说没有意义。
一般来说,在运行查询本身时,视图的性能几乎与性能完全相同。视图的优点就是将查询抽象出去,因此您不必考虑它。
您可以使用物化视图(或某些人说的“快照”),但您的数据只会与上次刷新时一样新。
答案 2 :(得分:1)
在对其中一个回复的评论中,该问题的作者解释说他正在寻找一种在MySQL中创建物化视图的方法。
MySQL并不像其他DBMS那样将物化视图的概念包装在一个很好的包中,但它确实拥有创建一个所需的所有工具。
您需要做的是:
如果您的基础表不经常更新,这可能会正常工作;但是,一旦执行此操作,您需要了解创建/更新/删除操作的额外成本。 此外,您还需要确保一些不知道您的技巧的DBA在没有迁移触发器的情况下不会迁移数据库。所以记录得很好。
答案 3 :(得分:0)
听起来像是过早优化,除非你知道这是一个明确而现实的问题。
MySQL没有实现视图,它们不比基表查询快。此外,在某些情况下,由于优化程度较低,因此速度较慢。
但是,视图还会“隐藏”未来维护代码的开发人员的东西,以使他们想象查询不像实际那样复杂。