1

我有一张带有客户收据的桌子。我正在尝试根据用户的姓名、地址和部门采购总额生成报告。所需的输出应如下所示


|Customer       |Address                | Clothing  | Electronics | Hardware | Household |
|Homer Simpson  | 724 Evergreen Terr    | $42       | $20         | $500     | $24       |  
|Walter White   | 308 Negra Arroyo Lane | $120      | $80         | $52      | $2400     |  

收据表是时间模型的一部分。因此,代码如下所示:

Select c.customername,a.address,r.receiptno,ir.department,ir.total
from customer c
inner join customer_address_lnk cal on cal.customerid = c.id
inner join address a on cal.addressid = a.id
inner join customer_receipts_lnk crl on crl.customerid = c.id
inner join receipts r on crl.receiptid = r.id
inner join receipts_receiptitem_lnk rrl on rrl.receiptid = r.id
inner join receiptitem ri on ri.id = rrl.receiptitemid

lnk 表是链接表。

收据项表具有以下列:ID、部门、金额、CreatedDate、UpdatedDate

这个想法是,如果收据被更新,更新后的金额可以针对退货、价格调整等进行调整。

目标是在 5 秒内完成查询。由于我们仅在receiptitems 表中就有超过1.25 亿行,因此需要SQL 20 多分钟来计算报告。

我已经尝试过 CTE 的观点但没有成功。我尝试过不同的 JOIN 订单。我用过左连接。甚至 Pivot 也没有减慢它的速度。我仍然无法在 20 分钟内完成它。

在我开始创建一个函数以使其低于 5 秒目标之前,我愿意接受任何建议。我目前更改索引的能力有限。

有什么想法吗?

4

1 回答 1

1

好吧,显然视图和 SQL 函数是不同的东西。

尝试使用将来需要向用户(可能是您自己!)明确返回的数据需要某些参数的函数,如果没有这些参数,数据就没有意义。有点像强迫用户包含 WHERE 子句。

在您的示例中,您可能希望强制用户按 CustomerId 或 ReceiptId 过滤。

然而....

在这种情况下,视图方法可能会更好。

  1. 根据设计,函数不使用临时表,而是使用表变量。作为变量的表比临时表慢得多。
  2. 您包含的查询非常简单,没有任何意外。该视图将是这里最简单和最好的方法。

对于 125M 行,我建议在处理期间检查执行计划(为此包括 WHERE 子句)或将数据转储到定期更新的汇总表中。或两者。一路检查索引。

这是更多(更好)的讨论测试 SQL 查询

于 2017-11-09T18:43:23.727 回答