The performance impact from multiple logical reads could be a result of your UDF.
Provided is a great article which describes using inline table-valued UDFs to reduce the row-by-row calls to the scalar UDF. UPDATE: I noticed you were already using table-valued UDF.
http://dataeducation.com/scalar-functions-inlining-and-performance-an-entertaining-title-for-a-boring-post/
To replicate your scenario, I executed the following query:
DECLARE
@Measurements TABLE(Precidence int, -- the relative scale of a measurement
Measurement varchar(max), -- Grams, Kilograms, Liters, etc
MeasurementType varchar(max)); -- Weight, Volume, etc`
DECLARE
@Items TABLE(ItemType varchar(max),
Quantity float,
Measurement varchar(max),
ToMeasurement varchar(max));
insert into @items (ItemType, Quantity, Measurement) values ('Widget','1','G');
insert into @items (ItemType, Quantity, Measurement) values ('Widget','1','KG');
insert into @items (ItemType, Quantity, Measurement) values ('Widget','1','ML');
insert into @items (ItemType, Quantity, Measurement) values ('Widget','1','L');
insert into @Measurements (Precidence, Measurement, MeasurementType) values ('2','G','Weight');
insert into @Measurements (Precidence, Measurement, MeasurementType) values ('1','KG','Weight');
insert into @Measurements (Precidence, Measurement, MeasurementType) values ('1','GAL','Volume');
insert into @Measurements (Precidence, Measurement, MeasurementType) values ('2','L','Volume');
insert into @Measurements (Precidence, Measurement, MeasurementType) values ('3','ML','Volume');
Afterwards, I complied and executed the following update statement:
WITH Items_CTE AS
(
SELECT A.ItemType,
A.Quantity,
A.Measurement,
(SELECT TOP 1 M.Measurement FROM @Measurements M
JOIN @Items C ON C.Measurement = M.Measurement
WHERE M.MeasurementType = B.MeasurementType
AND C.ItemType = A.ItemType
ORDER BY Precidence)ToMeasurement
FROM @Items A
JOIN @Measurements B
ON A.Measurement = B.Measurement
)
UPDATE @Items
SET ToMeasurement = cte.ToMeasurement
FROM ITEMS_CTE as cte
JOIN @Items as i
ON cte.measurement = i.measurement;
The UPDATE
statement uses a CTE and the results were as follows:
ItemType | Quantity | Measurement | ToMeasurement
Widget | 1 | G | KG
Widget | 1 | KG | KG
Widget | 1 | ML | L
Widget | 1 | L | L
Your UPDATE
statement is wrong. I've edited your TRIGGER
and the modifications I did and errors I saw:
Errors:
- You tried to drop a different
TRIGGER
that the one you're going to create. DROP TRIGGER IF EXISTS veevan.account_ai$$
.
- Why do you need the variable
@TargetLastMod
?. You didn't use it in the whole trigger
.
Modifications:
- I edited the
DROP TRIGGER
with veevan.address_vod__c_ai
instead veevan.account_ai
.
- I used a
JOIN
with the same fields of your SELECT
, with (address_vod__c.account_vod__c = NEW.account_vod__c AND targets.veeva_account_id=NEW.account_vod__c)
in the UPDATE
.
TRIGGER:
USE `veevan`;
DELIMITER $$
DROP TRIGGER IF EXISTS veevan.address_vod__c_ai$$
USE `veeva_new`$$
CREATE DEFINER=`root`@`localhost` TRIGGER `veevan`.`address_vod__c_ai` AFTER INSERT ON `address_vod__c` FOR EACH ROW
BEGIN
DECLARE vCount INT(6) DEFAULT 0;
SET vCount=(SELECT COUNT(*) FROM pdone.targets WHERE targets.veeva_account_id=NEW.account_vod__c);
IF (vCount>0) THEN
SET @TargetLastMod=(SELECT targets.lastSyncAt FROM pdone.targets WHERE targets.veeva_account_id=NEW.account_vod__c LIMIT 0,1);
UPDATE pdone.targets
JOIN veevan.address_vod__c AS avc ON (address_vod__c.account_vod__c = NEW.account_vod__c AND targets.veeva_account_id=NEW.account_vod__c)
SET
`address1` = avc.address1,
`address2` = avc.address2,
`city` = avc.city,
`state` = avc.state,
`zip` = avc.zip,
`phone` = avc.phone,
`fax` = avc.fax,
`lastSyncAt` = NOW(),
`updatedAt` = NOW()
WHERE address_vod__c.account_vod__c = NEW.account_vod__c
AND external_id_vod__c IS NOT NULL
AND address_vod__c.primary_vod__c = 1
AND account.recordtypeid COLLATE utf8_general_ci IN (SELECT id FROM veevan.recordtype WHERE name = 'Professional_vod');
END IF;
END$$
DELIMITER ;
Try it!
Best Answer
Assumptions:
L.L_EXTENDEDPRICE
should beL.L_EXTPRICE
L_DISCOUNT
andL_TAX
are percentages, in which case the values stored inLINEITEM
need to first be divided by 100.0 before performing calculationsSome sample data:
Contents of
ORDERS
before the update:Proposed update statement:
Contents of
ORDERS
after the update:Here's a rextester fiddle of the above.