我正在使用SQL Server 2008r2。由于大量连接,我有一个将数据返回给用户的问题(例如,我需要在一个查询中创建5个内部+6个左连接(通常是tvfs,有时是表)。这需要太长时间。)
此问题的解决方法是什么? 我应该对我的数据库进行denormolize吗? 避免大量连接的最佳做法是什么?
答案 0 :(得分:1)
我必须看到SQL来解决具体问题,但是在提取具有极高需求的结果时,我会做一些事情:
使用工具。显示估计执行计划可以在您的逻辑中暴露一些明显的变幻莫测。
学会爱'存在'和'拥有'。您可以通过以不需要HARD IO的创造性方式进行资格认证来最小化焦点和范围。对于子查询而不是连接更是如此,但我为每个需要的外连接添加了一个子句。
最重要的是IMO,不要害怕上演结果。您有时需要针对数百万条记录处理数十亿/数万亿的事务,并且通过分段可以在几分钟或几秒内完成连接需要数小时的事情。如果您只需要前2或3个表的x%,为什么要从上到下加入每个记录?有时它只是太多的开销。 将最简单的结果集下拉到阶段表(或临时,无论你需要什么),索引它然后继续下一个块。这通常会为我节省一笔财富。
尽可能使用CTE。但是,我的经验是它们已经降低到某个程度。很适合辅助表,但不适用于严重的数量。
在您的组合中发挥创意。我将在第1阶段使用那些存在子句(阅读表a,b和c),只返回表d,e和f中也存在的记录。
许多专家SQL建议不是基于VLDB - 它基于客户,订单,人口统计类型模式。
这些存储过程是否本机运行?
答案 1 :(得分:0)
这是一个很好的(过于简化的)分段示例:
假设您想要找到您所在城市的所有高风险人群(可能也很有趣)。您有一个电话公司dB(国家)索引按州,城市,姓氏,名字,地址和FBI dB(全球)索引的姓氏,名字,国家,地区,地址。假设由于多个过去的地址,FBI dB对每个人都有多条记录。
您可以在公共元素上加入两个dB,然后限定您的条件。要么... 从Phone选择RecordID作为P1 State ='MyState'和City ='MyCity'和 存在(选择1 从TheMan作为M1 其中M1.Last = P1.Last和M1.First = P1.First和M1.Risk> 80)
现在我有一个小的记录集来限定资格和一个小的结果集来工作。从那里我可以得到详细信息。这是CTE的一个很好的候选者,我可以在逻辑中射出十几个漏洞,但它说明了这个概念。如果将M1.Risk(非索引字段)带入具有完全连接的等式中,则会强制SQL Server在某些情况下针对它进行规划。不一定在这里,但随着你的逻辑变得更加复杂,随后的非索引标准发挥作用。