Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server SQL发票查询将信用转换为负数的性能_Sql Server - Fatal编程技术网

Sql server SQL发票查询将信用转换为负数的性能

Sql server SQL发票查询将信用转换为负数的性能,sql-server,Sql Server,我有一个第三方数据库,其中包含我需要报告的发票数据。无论“发票”是贷方备忘还是实际发票,“数量”和“金额”字段都存储为正数。有一个单字符字段包含类型“I”=发票,“R”=信用 在一份相当于140万条记录的报告中,我需要对这些数据求和,以便从总记录中减去信用,将发票加到总记录中,我需要对报告中的8个不同列(本年度、上一年度等)这样做 我的问题是实现这一点的许多不同方法的性能 最佳表现似乎是在等式中使用案例陈述,如下所示: Case WHEN ARH.AccountingYear - 2 = @iC

我有一个第三方数据库,其中包含我需要报告的发票数据。无论“发票”是贷方备忘还是实际发票,“数量”和“金额”字段都存储为正数。有一个单字符字段包含类型“I”=发票,“R”=信用

在一份相当于140万条记录的报告中,我需要对这些数据求和,以便从总记录中减去信用,将发票加到总记录中,我需要对报告中的8个不同列(本年度、上一年度等)这样做

我的问题是实现这一点的许多不同方法的性能

最佳表现似乎是在等式中使用案例陈述,如下所示:

Case WHEN ARH.AccountingYear - 2 = @iCurrentYear THEN ARL.ShipQuantity * (CASE WHEN InvoiceType = 'R' THEN -1 ELSE 1 END) ELSE 0 END as PPY_INVOICED_QTY
但就代码可读性而言,这是非常难看的,因为我必须对8个不同的列进行操作,性能很好,在16秒内针对所有1.4M记录运行

使用标量UDF会降低性能

Case WHEN ARH.AccountingYear - 2 = @iCurrentYear THEN ARL.ShipQuantity * dbo.fn_GetMultiplier(ARH.InvoiceType) ELSE 0 END as PPY_INVOICED_QTY
大约需要5分钟。所以我不能这么做

我能想到的其他选择是:

  • 多个级别的视图,使用新视图添加乘数列,然后从中选择并使用新列执行乘法
  • 构建一个包含两列和两条记录的表,R,-1和I,1,并基于InvoiceType连接它,但这似乎太过分了

  • 我还缺少任何其他想法,或者关于这类事情的最佳实践的建议?我无法更改由第三方应用程序建立的存储数据。

    我决定按照Igor的建议使用多个视图,实际上使用嵌套版本,尽管可读性较低,但维护更容易,因为只有一个命名视图而不是两个。性能类似于8个不同的case语句,因此总体运行时间不到20秒


    感谢您的见解。

    我决定按照Igor的建议使用多视图,实际上使用嵌套版本,尽管可读性较低,但维护更容易,因为只有一个命名视图而不是两个。性能类似于8个不同的case语句,因此总体运行时间不到20秒


    感谢您提供的见解。

    您能否更改模式并根据发票类型添加计算列?这将使其更具可读性,但也可能提高性能。不幸的是,我不允许在不取消支持合同的情况下以任何方式更改第三方表。在这种情况下,一个或多个视图可能是您的最佳选择。根据所包含的内容,您可能能够创建一个表,该表可能会稍微提高性能。或者,如果报表用户对半陈旧的数据满意,您可以创建自己的表,并以适合于报表的形式加载数据。您也可以对其进行聚合,使其不再基于事务。在许多情况下,这是可以接受的。然后,根据您的需求,您可以计算出数据的年龄,并根据该频率进行更新,就像使用每XX次运行一次的Sql作业一样。这是一种折衷办法,要么实时数据的性能较慢,要么数据稍旧,但结果却很快。@Igor,实际上,它目前是用过时的数据来完成的,通过许多级别的存储过程和视图填充这些数据需要9分钟(并使用52个不同的SQL对象)。我正在尝试将其转换为实时数据并使其更易于理解,目前仅访问8个SQL对象。因此,我犹豫是否让代码难以阅读,或者在并非绝对需要的地方添加额外的视图层。但始终是一种平衡行为。:)是否可以更改架构并根据发票类型添加计算列?这将使其更具可读性,但也可能提高性能。不幸的是,我不允许在不取消支持合同的情况下以任何方式更改第三方表。在这种情况下,一个或多个视图可能是您的最佳选择。根据所包含的内容,您可能能够创建一个表,该表可能会稍微提高性能。或者,如果报表用户对半陈旧的数据满意,您可以创建自己的表,并以适合于报表的形式加载数据。您也可以对其进行聚合,使其不再基于事务。在许多情况下,这是可以接受的。然后,根据您的需求,您可以计算出数据的年龄,并根据该频率进行更新,就像使用每XX次运行一次的Sql作业一样。这是一种折衷办法,要么实时数据的性能较慢,要么数据稍旧,但结果却很快。@Igor,实际上,它目前是用过时的数据来完成的,通过许多级别的存储过程和视图填充这些数据需要9分钟(并使用52个不同的SQL对象)。我正在尝试将其转换为实时数据并使其更易于理解,目前仅访问8个SQL对象。因此,我犹豫是否让代码难以阅读,或者在并非绝对需要的地方添加额外的视图层。但始终是一种平衡行为。:)