【iDempiere Lab】C_OrderテーブルのBill_BPartner_IDカラムにインデックスのススメ

現在、JPiere/iDempiereのパフォーマンス検証の一環としてボリュームテストを実施しており、目標としている1億明細までもう少しといった所です。ボリュームテストでは受注伝票(10明細)->出荷納品伝票(10明細)->売上請求伝票(10明細)の登録をひたすら行っています。

データ量が多くなってきたことに伴い、この受注伝票(10明細)->出荷納品伝票(10明細)->売上請求伝票(10明細)と登録するのに時間がかかるようになってきました。データ量も受注伝票明細で8000万明細を超えてきて受注伝票(10明細)->出荷納品伝票(10明細)->売上請求伝票(10明細)を1巡するのに10秒弱かかるようになり、ある程度遅くなるのはしょうがないかなと思っていたのですが、このままだと目標の1億明細までレコード数としてはあと少しでも時間的には結構かかってしまうので、なんとかならないかなと思って、ボトルネックとなっている所をソースコードを精査して探してみました。

そうしたら、ありました!!

MInOutクラスのprepareIt()メソッドの中にある下記の処理がボトルネックとなっていました。

BigDecimal notInvoicedAmt = MBPartner.getNotInvoicedAmt(getC_BPartner_ID());

if (MBPartner.SOCREDITSTATUS_CreditHold.equals(bp.getSOCreditStatus(notInvoicedAmt)))

{

m_processMsg = "@BPartnerOverSCreditHold@ - @TotalOpenBalance@="

+ bp.getTotalOpenBalance() + ", @NotInvoicedAmt@=" + notInvoicedAmt

+ ", @SO_CreditLimit@=" + bp.getSO_CreditLimit();

return DocAction.STATUS_Invalid;

}

未請求金額を取得する処理( MBPartner.getNotInvoicedAmt(getC_BPartner_ID()) )の中で、C_OrderテーブルのBill_BPartner_IDを条件にSELECT文を発行している所があるのですが、Bill_BPartner_IDにインデックスがはられていなかったため、受注伝票が増えるにしたがってパフォーマンスの低下につながっていました。

C_OrderテーブルのBill_BPartner_IDにインデックスをはった所、いままで受注伝票(10明細)->出荷納品伝票(10明細)->売上請求伝票(10明細)を1巡登録するのに10秒弱かかっていたのが、ものの一瞬(1秒くらい?)で処理できるようになりました!!

こんなに爆速になるのであれば、もっと早く気が付きたかった!! (*^。^*)

でも、これこそがボリュームテストを実施している成果ですね。データ件数が少ないうちは気が付くのは難しかったかなと思います。

これで、受注 -> 出荷 -> 請求 -> 入金と一連の取引の流れでは、DBのインデックスはかなり最適化されたのではないかと思います。現在、受注伝票が900万伝票で明細が9000万明細近くになっていますが、伝票の登録、伝票ステータスの更新、転記と、とても元気に処理する事ができています。

iDempiere/JPiereを使用されている方は、ぜひC_OrderテーブルのBill_BPartner_IDカラムにインデックスをはって下さい。受注伝票のデータ量が少ない時は体感できないかもしれませんが、インデックスをはって頂ければ受注伝票が多くなってきても、出荷納品伝票をスムーズに完成にできるはずです!!

【JPIERE-0179】トランザクションテーブルへのインデックス追加 でがんばってインデックスをはりましたが、ボリュームテストでその効果を確認していくのはやっぱり大切ですね。これからもパフォーマンスについては継続的に追及してきたいと思っています。

参考:JPiereのパフォーマンス改善への取り組み

関連するコンテンツ