当前位置: 首页>>技术问答>>正文


重复列以加快查询速度?

webfans 技术问答 , , 去评论

问题描述

标题没有多大意义,但我想不出更好的标题来解决这个问题。

我有以下表格

项目

  • ID

  • 名称

顾客

  • ID

  • id_project

  • 名称

支付

  • ID

  • id_customer

  • 日期

当用户进入系统时,他将可以访问某个项目。现在,我想列出该项目的所有付款,这应该很简单:

SELECT FROM payments where id_customer in (SELECT id from customers where id_project = 5)

我的问题是:如果以这种方式将列id_project添加到付款表不是更好,那么查询将更容易,更快。

最佳解决方案

看来你问denormalization是否合理。

Denormalization is the process of attempting to optimize the read performance of a database by adding redundant data or by grouping data. In some cases, denormalization helps cover up the inefficiencies inherent in relational database software. A relational normalized database imposes a heavy access load over physical storage of data even if it is well tuned for high performance.

答案总是”it depends”,所以这是我的经验法则:

如果…

  • 数据量不大

  • 你已经没有做过大量的加入了

  • 和/或数据库性能目前不是瓶颈

然后保持正常化。是的,非规范化更快,但它也意味着您在系统中有冗余数据 – 必须维护并保持同步的数据。该数据不再有”one source”,而是可以偏离的多个来源。随着时间的推移,这是有风险的,所以除非你有充分的理由去做,否则你不应该这样做,有一些基准支持。

我只会在…时反规范化

  • 数据量非常大

  • 连接是昂贵的,你必须做很多,以获得返回的简单查询

  • 数据库性能是一个瓶颈和/或您希望尽可能快地进行

在现代硬件上加入非常快,但它们永远不会自由。

次佳解决方案

您最好将查询重写为:

SELECT payments.*
FROM   customers
JOIN   payments 
ON     payments.id_customer = customers.id
WHERE  customers.id_project = 5

虽然这看起来不那么简洁,但是一个好的查询规划器会看到你要做的事情,并将相关的sub-query作为上面的连接运行,一个错误的查询规划器可能最终会对payments.id_customer进行索引扫描(假设你有一个相关的索引) (或更糟糕的是,表扫描)而不是以更有效的方式做事。即使是一个好的查询规划器,如果这个查询的排列包含在更复杂的东西中,也可能无法看到优化​​。将关系表示为连接而不是sub-query可能比更改数据结构更有意义。

正如杰夫所说,任何非规范化都应该谨慎考虑 – 它可以带来轻松的性能提升,特别是对于某些报告目的,但由于支持业务逻辑中的错误可能导致不一致。

作为旁注:显然我不了解你的业务,所以我可能会遗漏一些东西,但你的桌子关系对我来说似乎很奇怪。他们暗示你永远不会有同一个客户的多个项目,这在我的经验中通常是不正确的,至少在很长一段时间内都是如此。

customer     project      payment
--------     --------     -------
                          pa_id
             pr_id    <-- payment
cu_id    <-- customer     

或者如果不那么正常化(虽然我怀疑这是必要的):

customer     project      payment
--------     --------     --------
                          pa_id
             pr_id    <-- payment
cu_id    <-- customer 
           `------------- customer    

当然,这仍然打折了与两个客户联合项目的可能性……

第三种解决方案

在某些数据库中,您可以基于复杂的查询创建”Materialized Views”而不是具有大量数据的复杂VIEWS。这可以用于避免在历史增长的应用程序系统中进行非规范化。如果您决定使用”Materialized Views”,则必须清楚地了解物化视图将使用的刷新方法和存储量…

参考资料

本文由朵颐IT整理自网络, 文章地址: https://duoyit.com/article/3037.html,转载请务必附带本地址声明。