说到数据库,我几乎是个白痴,我可以编写查询来做我想做的事而不会出现太多问题,但是当我遇到性能问题时,我真的不知道该怎么做,所以任何帮助都将不胜感激已收到。
我有三张桌子:
账单
- Bill_Id - BIGINT - 主键
- 账单日期 - 日期
账单详情
- BillDetail_Id - BIGINT - 主键
- Bill_Id - BIGINT - 比尔的外键,索引
- BillDetailType_Id - INT - BillDetailType 的外键,索引
- 收费 - 钱
账单明细类型
- BillDetailType_Id - INT - 主键
- 类型名称 - NVARCHAR(20)
每个账单都有多个 BillDetails,它们基本上是账单上的各个项目。每个BillDetail 都有一个BillDetailType,它是什么类型的账单项目(例如电费、互联网、税收)。
我还创建了这样的视图:
CREATE VIEW BillSubtotal
AS
SELECT b.*,
(SELECT SUM(bd.Charge) FROM BillDetail AS bd INNER JOIN BillDetailType AS bdt ON bd.BillDetailType_Id = bdt.BillDetailType_Id
WHERE (bdt.TypeName = 'Tax') AND (bd.Bill_Id = b.Bill_id)) AS Tax,
(SELECT SUM(bd.Charge) FROM BillDetail AS bd INNER JOIN BillDetailType AS bdt ON bd.BillDetailType_Id = bdt.BillDetailType_Id
WHERE (bdt.TypeName <> 'Tax') AND (bd.Bill_Id = b.Bill_id)) AS NonTaxTotal
FROM Bill AS b
使用当前的开发数据库运行该视图大约需要 14 秒,其中大约有 60000 个账单和 700000 个账单详细信息。有 26 种不同的 BillDetailType。一旦我得到这个工作,我想添加更多的小计,但现在这就是我所拥有的。
现在我正在尝试进行这样的加入:
SELECT bs.BillDate, bs.Tax, bs.NonTaxTotal, bd.Charge, bdt.TypeName FROM
BillDetail bd
INNER JOIN BillSubtotal bs ON bs.Bill_Id = bd.Bill_Id
INNER JOIN BillDetailType bdt ON bdt.BillDetailType_Id = bd.BillDetailType_Id
我想计算一个特定的 BillDetail 占税前账单的百分比以及其他一些东西,所以我最终会得到类似 bd.Charge/bs.NonTaxTotal*100 的东西,但目前这个查询需要 14小时才能运行我真的不明白为什么。
如果我删除任何一个 INNER JOIN,查询会大大加快:
SELECT bs.BillDate, bs.Tax, bs.NonTaxTotal, bd.Charge FROM
BillDetail bd
INNER JOIN BillSubtotal bs ON bs.Bill_Id = bd.Bill_Id
运行大约需要 1.5 分钟。
SELECT bd.Charge, bdt.TypeName FROM
BillDetail bd
INNER JOIN BillDetailType bdt ON bdt.BillDetailType_Id = bd.BillDetailType_Id
大约需要 12 秒。
我不明白为什么任何一个连接都可以在这么短的时间内运行,但是当我一起连接时需要几个小时。也许这是非常明显的事情,但是因为我并不真正了解如何评估查询,所以我错过了它。我查看了执行计划,但我无法从中收集到任何有用的信息,我有点走投无路了。我尝试了各种切换方式,将其中一个连接移动到子查询以及我认为可能有帮助的其他事情,但我所做的一切都没有改变性能。
谢谢你的帮助。