简体   繁体   English

SQL 视图,性能和计数从一对多的关系

[英]SQL view, performance and count from one-to-many relationship

I need some help with forming basic SQL-VIEWs for a bunch of my tables.我需要一些帮助来为我的一堆表构建基本的 SQL-VIEW。 Here's a quick overview这是一个快速概述

  • I've a ClaimDetail table and it has got some Lookup fields like StatusID, BrandID, SalespersonID, etc..我有一个 ClaimDetail 表,它有一些查找字段,如 StatusID、BrandID、SalespersonID 等。
  • As usual, the lookup fields map to master tables like MasterStatus, MasterBrand, ... {Structure: ID, Title}像往常一样,查找字段 map 到 MasterStatus、MasterBrand 等主表... {结构:ID、标题}
  • Also there're two other tables Comments and Files.还有另外两个表评论和文件。 A Claim can have multiple Comments and multiple Files.一个声明可以有多个评论和多个文件。
  • I need to display a Dashboard which will be a list of Claims.我需要显示一个仪表板,它将是一个索赔列表。 I need to display titles from the Master tables and count of the comments & files.我需要显示主表中的标题以及评论和文件的数量。

Now, I've two views of this Dashboard one is for users of type Customer which is limited to certain details and another one is a detailed view which is meant for Internal users.现在,我有这个仪表板的两个视图,一个是针对客户类型的用户的,它仅限于某些细节,另一个是针对内部用户的详细视图。 You can say that the Customer view is a sub-set of the Internal view.您可以说客户视图是内部视图的子集。

I see two options -我看到两个选项 -

  1. Opt#1: Create a single vw_Internal view and use it to fetch data for both the Users.选项#1:创建单个 vw_Internal 视图并使用它为两个用户获取数据。
  2. Opt#2: I create a vw_Customer which has onlt those fields which are required for the Customer and then I create a vw_Internal which will be like: vw_Customer INNER JOIN Master tables.选项#2:我创建了一个vw_Customer ,它只包含客户所需的那些字段,然后我创建一个vw_Internal ,它类似于:vw_Customer INNER JOIN 主表。 In short I'll extend the basic vw_Customer to include more fields.简而言之,我将扩展基本的 vw_Customer 以包含更多字段。

Does option#2 make sense from speed and performance point of view?从速度和性能的角度来看,选项#2 是否有意义? Opt#1 is simple but considering the huge number of records I want to make sure that the Customers don't have to wait a bit longer for those extra lookups which not are going to be included in their Dashboard.选项#1 很简单,但考虑到大量记录,我想确保客户不必为那些不会包含在仪表板中的额外查找等待更长的时间。

Finally, is there a way for the last feature I mentioned?最后,有没有办法实现我提到的最后一个功能? That is getting the count of Comments and Files which has a one-to-many relationship with the ClaimDetail table .这是获取与 ClaimDetail 表具有一对多关系的 Comments 和 Files 的计数 I just need the count or atleast a boolean field which says whether a claim has any Comments or not (Same for Files) - if'll be false if the count = 0. I'm also concerned about the performane impact due to this feature.我只需要计数或至少一个 boolean 字段,该字段说明索赔是否有任何评论(文件相同)-如果计数 = 0,则为假。我也担心此功能对性能的影响.

Thanks in advance.提前致谢。

With regards to the view definitions, I'd build two views, and I'd make them separate--neither view would reference the other.关于视图定义,我将构建两个视图,并将它们分开——两个视图都不会引用另一个。 This would allow you to optimize the queries independantly, and it avoids any problems you'd get with views layered on top of views;这将允许您独立优化查询,并避免您在视图分层视图时遇到的任何问题; too many layers can make databases management, maintenance, and refactoring particularly challenging.太多的层会使数据库管理、维护和重构特别具有挑战性。

As for the data aggregation, common tactics include the following.至于数据聚合,常见的策略包括以下几种。 Compare, contrast, test, and extrapolate to see what fits best in your environment:比较、对比、测试和推断,看看什么最适合您的环境:

Subqueries子查询

SELECT mt.Id, st1.HowMany, st2.HowManyOther, <etc>
 from MainTable mt
  inner join (select Id, count(*) HowMany
               from SubTable1
               group by Id) st1
   on st1.Id = mt.Id
  inner join (select Id, count(*) HowMany
               from SubTable2
               group by Id) st2
   on st2.Id = mt.Id

Fairly straightforward, though the subqueries might get kind of costly, even with proper indexing.相当简单,尽管子查询可能会变得有点昂贵,即使有适当的索引。

count(distinct xx)计数(不同的 xx)

SELECT mt.Id, count(distinct st1.UniqueKey) HowMany, count(distinct st2.UniqueKey) HowManyOther, <etc>
 from MainTable mt
  inner join SubTable1 st1
   on st1.Id = mt.Id
  inner join SubTable2
   on st2.Id = mt.Id

This requires a single unique column in the "subtables", and gets messy if you have to deal with outer joins or NULLs.这需要“子表”中的单个唯一列,如果您必须处理外部连接或 NULL,则会变得混乱。


Added添加


First, replacing the inner joins with (left) outer joins in either of the above queries will produce 0+ counts from the subtables, so long as you make sure the count is being done on the “right” table (because NULLs don't get tallied).首先,在上述任一查询中用(左)外连接替换内连接将从子表中产生 0+ 计数,只要您确保计数是在“右”表上完成的(因为 NULL 不会得到统计)。 To figure out which performs best on your environment, you'd have to write and test both queries.要确定哪个在您的环境中表现最好,您必须编写和测试这两个查询。 I'd guess the second, since the first requires table scans on the tables of the subqueries while the second performs joins and so may optimize better, but the SQL query optimizer is smarter than me (because it knows your indexes and has distribution histograms of your data) so you want to see what it comes up with.我猜是第二个,因为第一个需要对子查询的表进行表扫描,而第二个执行连接,因此可能会优化得更好,但是 SQL 查询优化器比我更聪明(因为它知道您的索引并具有分布直方图你的数据)所以你想看看它会带来什么。

With regards to “layered views”, if I'm following the logic right, I'd recommend building the Internal view as the complex/comprehensive query (all the joins, all the relevant columns), and then build the Customer view that's hopefully as simple as关于“分层视图”,如果我遵循正确的逻辑,我建议将内部视图构建为复杂/全面的查询(所有连接、所有相关列),然后构建希望的客户视图简单到

SELECT <customerOnlyColumns>
 from vw_Internal

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM