データベースに関して言えば、私はほとんどばかです。あまり問題なく、やりたいことを行うためのクエリを書くことができますが、パフォーマンスの問題に遭遇したとき、何をすべきか本当にわかりません。受け取った。
私は3つのテーブルを持っています:
明細書
- Bill_Id - BIGINT - 主キー
- 請求日 - DATE
BillDetail
- BillDetail_Id - BIGINT - 主キー
- Bill_Id - BIGINT - Bill の外部キー、インデックス付き
- BillDetailType_Id - INT - 索引付けされた BillDetailType の外部キー
- お金をチャージ
BillDetailType
- BillDetailType_Id - INT - 主キー
- タイプ名 - NVARCHAR(20)
各 Bill には複数の BillDetails があり、基本的には Bill の個々の項目です。すべての 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
このビューの実行には、約 60000 Bills と 700000 BillDetails を持つ現在の開発データベースで約 14 秒かかります。26 の異なる BillDetailTypes があります。これが機能するようになったら、さらに小計を追加したいと思いますが、今のところはそれだけです。
今、私はこのような結合をしようとしています:
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秒かかります。
どちらの結合も短時間で実行される理由はわかりませんが、結合を一緒に実行すると数時間かかります。たぶんそれは非常に明白なことですが、クエリがどのように評価されているのかよくわからないので、見逃しています。私は実行計画を見ましたが、そこから有用なものを得ることができず、行き詰まっています。結合の 1 つをサブクエリに移動するなど、さまざまな方法で切り替えを試みましたが、パフォーマンスが変わることはありませんでした。
助けてくれてありがとう。