我们是否遇到过SQL Server由于引用过多表而无法执行的查询?

时间:2020-03-05 18:37:45  来源:igfitidea点击:

我们是否看到过任何错误消息?

-- SQL Server 2000
  
  Could not allocate ancillary table for view or function resolution.

  The maximum number of tables in a query (256) was exceeded.
  
  -- SQL Server 2005
  
  Too many table names in the query. The maximum allowable is 256.

如果是,我们做了什么?

放弃了?说服客户简化需求?对数据库进行非规范化?

@(每个人都希望我发布查询):

  • 我不确定是否可以在答案编辑窗口中粘贴70 KB的代码。
  • 即使我能做到这一点也无济于事,因为这70 KB的代码将引用我也必须发布的20或者30个视图,因为否则该代码将毫无意义。

我不想听起来好像在吹牛,但问题不在查询中。查询是最佳的(或者至少几乎是最佳的)。我花了无数小时来优化它们,寻找可以删除的每一个列和每个表。假设一个报表有200或者300列,而该报表必须用一个SELECT语句填充(因为几年前它还是一个小报表时就这样设计)。

解决方案

回答

我从来没有遇到过这种情况,老实说,在查询中引用> 256个表的想法使我感到非常恐惧。

第一个问题可能是"为什么那么多?",紧接着是"我不需要什么信息?"我担心从这样的查询返回的数据量也会开始严重影响应用程序的性能。

回答

我希望看到该查询,但是我想这是某种迭代器的问题,尽管我无法想到任何可能的情况,但我敢打赌,这是由于糟糕的while / case / cursor或者大量的实施效果不佳的视图。

回答

@chopeen我们可以更改计算这些统计信息的方式,而是保留所有每个产品统计信息的单独表..下订单时,遍历产品并更新统计信息表中的相应记录。这会将大量计算负荷转移到结帐页面,而不是在运行报表时在一个大型查询中运行所有内容。当然,有些统计信息无法通过这种方式很好地发挥作用,例如购买特定产品后跟踪客户的下一次购买。

回答

对于SQL Server 2005,我建议我们使用表变量并随需而建部分数据。

为此,请创建一个表变量,该变量代表要发送给用户的最终结果集。

然后找到主表(例如上面示例中的orders表)并提取该数据,以及一些补充数据,这些补充数据仅表示一个联接(客户名称,产品名称)。我们可以执行SELECT INTO将其直接放入表变量中。

从那里开始,遍历表,并针对每一行,执行一堆小的SELECT查询,以检索结果集所需的所有补充数据。将它们插入到每一列中。

完成后,我们可以从表变量中执行简单的SELECT *,并将此结果集返回给用户。

我对此没有任何确切的数字,但是到目前为止,我已经研究了三个不同的实例,在这些实例中,执行这些较小的查询实际上比执行带有大量联接的大规模选择查询要快。

回答

发表查询:D

我也觉得可能的问题之一可能是一吨(读取200多个)名称/值表,这些表可能会浓缩为一个查找表。

回答

编写在SQL Server 2000上运行的Dynamics CRM安装的Reporting Services报表时,总是会发生这种情况。CRM具有很好的规范化数据架构,会导致大量联接。实际上有一个修补程序可以将限制从256个增加到最大260个:http://support.microsoft.com/kb/818406(我们一直认为这对SQL Server团队来说是一个很好的笑话)。

正如Dillie-O坚持的那样,解决方案是识别适当的"子联接"(最好是多次使用的子联接)并将它们分解为临时表变量,然后在主联接中使用它们。它是主要的PIA,通常会降低性能。我为你感到难过。

@Kevin,喜欢开球的人-说完了:-)。

回答

我遇到了同样的问题...我的开发箱运行SQL Server 2008(视图工作正常),但在生产环境中(使用SQL Server 2005)视图却没有。为了避免这种限制,我最终创建了视图,将新视图用作引发错误的视图中查询的一部分。

有点傻,认为逻辑执行是相同的...