私はOracleクエリに取り組んでおり、それをより速くする必要があります。アドバイスをいただければ幸いです。
- データベースは Oracle で、ExaData クラスターで実行されます。
- Oracle バージョン: Oracle Database 11g Enterprise Edition リリース 11.2.0.3.0 - 64 ビット製品
私は2つのテーブルを持っています。
1) トランザクション: 店舗での購入 - TransactionID
2)TransactionItems:各購入には1..多くのアイテムがあります-TransactionID、ItemID
各テーブルには、次の 2 つのフラグがあります。
- FlagA: はい/いいえ
- FlagB: はい/いいえ
クエリは次のことを行う必要があります。
- TransactionItem のすべてのレコードに FlagA と FlagB の値を設定します。
- TransactionItem の Flags の値に基づいて、Transaction の各行の FlagA と FlagB の値を設定します。
クエリを 4 つのステップに分けました。
- TransactionItem のフラグ A の値を設定する
- TransactionItem のフラグ B の値を設定する
- トランザクションのフラグ A の設定値
- トランザクションのフラグ B の設定値
クエリはスムーズに実行されます。ただし、これが問題です。何十億ものトランザクション レコードがあり、各トランザクションには約 7 つのトランザクション アイテムがあります。
現在の速度は次のとおりです。
- 合計時間: 616 秒 / 10.27 分
- 毎秒 1,218 トランザクション / 毎分 73,000 トランザクションを処理
各ステップの処理時間を追跡しました。
TransactionItem のフラグ A の値を設定する
- 4分52秒
TransactionItem のフラグ B の値を設定する
- 3分26秒
トランザクションのフラグ A の設定値
- 1分6秒
トランザクションのフラグ B の設定値
- 0分51秒
以下は私の完全なクエリです。他に使用したテーブルはこちら
製品
- 各 TransactionItem には ProductId があります。 各製品には ProductCode があります。
- 1 つの製品コードには多くの製品があります
フラグ製品コード
- FlagA として分類される ProductCodes のリストを含む 1 つの列
フラグB製品コード
- FlagB として分類される ProductCodes のリストを含む 1 つの列
取引支払
- これは、各トランザクションの支払いの詳細を含むファクト テーブルです。
Payment_Dim
- PaymentID の TransactionPayment へのリンク
- これは、FlagB が Payment_Dim.PaymentName に基づいて設定されているために必要です。
私はこれらのインデックスを持っています:
トランザクション 1.TransactionID
TransactionItems 1.TransactionID 2.ProductID
製品 1. 製品 ID 2. 製品コード
FlagAproductCodes 1. ProductCode
FlagBproductCodes 1. ProductCode
支払い 1. PaymentID 2. PaymentCode 3. Payment_Name
助けてくれて本当にありがとう、ありがとう
-- 1. Set value of FlagA for TransactionItem
Update
TransactionItems Item
Set FlagA =
(
Select
Case
When
Item.FlagA_Qty = 0 Then 'N' -- this is the quantity of items purchased that fall into the FlagA category
When
FlagA.ProductCode Is Null Then 'N'
Else
'Y'
End
From
Product Prod
Left Join
FlagAproductCodes FlagA
On Product.ProductCode = FlagA.ProductCode
Where
Product.Prod_Id = Item.Prod_Id
)
;
-- 2. Set value of FlagB for TransactionItem
Update TransactionItems
Set FlagB = 'Y'
Where ItemID In
(
Select
Trans_Items.ItemID
From
TransactionItems Trans_Items
Inner Join Product Prod
On Trans_Items.Prod_Id = Product.Prod_Id
Inner Join FlagBproductCodes FlagB
On Product.ProductCode = FlagB.ProductCode
Where
(
Trans_Items.Gov_FlagA_Qty < Trans_Items.Item_Qty
)
AND
(
Exists
(Select Transaction_Payment_Fid
From TransactionPayment Trans_Pay
Inner Join Warehouse.Payment_Dim Pay_Dim
On Trans_Pay.Payment_Id = Pay_Dim.Payment_Id
Where
Transaction_Fid = Trans_Items.Transaction_Fid
And Upper(Pay_Dim.Payment_Name) Like '%ABC%'
)
)
)
;
Update TransactionItems
Set FlagB = 'N'
Where FlagB Is Null;
-- 3: Set FlagA for Transactions
Update
Transactions
Set
Gov_FlagA_Flag =
Case When Exists
(Select ItemID
From TransactionItems Item
Where Item.Transaction_Fid = Transactions.Transaction_Fid
and gov_FlagA_flag = 'Y')
Then 'Y'
Else 'N'
End
;
-- 4: Set FlagB for Transactions
Update
Transactions
Set
FlagB =
Case When Exists
(Select ItemID
From TransactionItems Item
Where Item.Transaction_Fid = Transactions.Transaction_Fid
And FlagB = 'Y')
Then 'Y'
Else 'N'
End
;