Reputation: 609
I've been working on improving the performance of a stored procedure and there is a big slow down due to having to run four very similar updates.
I've found information on similar troubles in MySql which was helpful but I could not implement what I had learned, perhaps Oracle operates differently.
Among the things I've tried are; a batch insert through merge, creating a secondary temp_table and working with no temp tables at all but there has been no improvement.
Being new to Oracle it's entirely possible I'm just going about it the wrong way.
Any advice or answers or directions to answers would be greatly apreciated as I've run out of ideas and working now with nothing but brute force and ignorance.
UPDATE TEMP_TABLE TI SET T.ItemPrice_One =
(
SELECT ItemPrice
FROM Temp.View_Items V
WHERE V.Item_Name = 'Item_Name_One'
AND V.ID = T.ID
AND V.Date = T.Date
);
UPDATE TEMP_TABLE TI SET T.ItemPrice_Two =
(
SELECT ItemPrice
FROM Temp.View_Items V
WHERE V.Item_Name = 'Item_Name_Two'
AND V.ID = T.ID
AND V.Date = T.Date
);
UPDATE TEMP_TABLE TI SET T.ItemPrice_Three =
(
SELECT ItemPrice
FROM Temp.View_Items V
WHERE V.Item_Name = 'Item_Name_Three'
AND V.ID = T.ID
AND V.Date = T.Date
);
Upvotes: 2
Views: 11721
Reputation: 48111
What you're trying to do is essentially a pivot operation -- turning multiple row values into multiple column values in a single row. Below is one method using a common technique in Oracle for doing pivot queries (untested but I think it should work as-is). As of version 11g there is a built-in PIVOT operation, but I have not really looked at it yet -- it may be a more direct method of doing what you need.
UPDATE TEMP_TABLE TI SET ( T.ItemPrice_One, T.ItemPrice_Two,T.ItemPrice_Three ) =
(
SELECT
MAX( CASE WHEN V.Item_Name='Item_Name_One' THEN ItemPrice ELSE NULL END ) Item_Price_One,
MAX( CASE WHEN V.Item_Name='Item_Name_Two' THEN ItemPrice ELSE NULL END ) Item_Price_Two,
MAX( CASE WHEN V.Item_Name='Item_Name_Three' THEN ItemPrice ELSE NULL END ) Item_Price_Three
FROM Temp.View_Items V
WHERE V.ID = T.ID
AND V.Date = T.Date
);
Upvotes: 2
Reputation: 9150
Maybe you can try exploring the use of the MERGE statement. It may allow you to avoid doing three scans of the view table. I don't have an instance to experiment with, but here is a rough guess of the idea:
MERGE INTO TEMP_TABLE t
USING (SELECT Item_name, ItemPrice
FROM Temp.View_Items V
WHERE V.Item_Name IN ('Item_Name_One', 'Item_Name_Two', 'Item_Name_Three')
AND V.ID = T.ID
AND V.Date = T.Date) s
ON (...join condition here... t.item_name = v.item_name??)
WHEN MATCHED THEN
UPDATE SET t.ItemPrice_One = DECODE(s.ItemPrice, 'Item_Name_One', v.ItemPrice, t.ItemPrice_One)
,t.ItemPrice_Two = DECODE(s.ItemPrice, 'Item_Name_Two', v.ItemPrice, t.ItemPrice_Two)
,t.ItemPrice_Three = DECODE(s.ItemPrice, 'Item_Name_Three', v.ItemPrice, t.ItemPrice_Three);
Upvotes: 1
Reputation: 1547
UPDATE TEMP_TABLE TI SET T.ItemPrice_One =
(
SELECT ItemPrice
FROM Temp.View_Items V
WHERE V.Item_Name = 'Item_Name_One'
AND V.ID = T.ID
AND V.Date = T.Date
)
, T.ItemPrice_Two =
(
SELECT ItemPrice
FROM Temp.View_Items V
WHERE V.Item_Name = 'Item_Name_Two'
AND V.ID = T.ID
AND V.Date = T.Date
)
, T.ItemPrice_Three =
(
SELECT ItemPrice
FROM Temp.View_Items V
WHERE V.Item_Name = 'Item_Name_Three'
AND V.ID = T.ID
AND V.Date = T.Date
);
Upvotes: 0