I am not a db expert so I hope someone can give me a pointer. Is there an advantage of using a vanilla approach vs an upsert appoach. I find the vanilla approach clearer with no obvious side effects.
This table is a summary table created from time consuming reads and calculations (average 3-4 seconds to complete). This table is disposable (it can be truncated at any time). This table receives a lot of updates and reads with minimal inserts.
Initially each read access would update and then read the data. To improve performance, I added a 5 minute delay between updates
- after an update occurs for a group, for the next 5 minutes users in that group will only read the data (saving 3-4 seconds)
- the first access after the 5 minutes has elapsed will trigger a full update for the group data
Initially I implemented an upsert algorithm. However a side effect of the upsert-insert is that the auto-increment pk field is updated with every execution. This resulted in a jump of 100000 for that key in a few hours. My concern is not the gaps, but hitting the max value for an int. I can manage this by either removing the auto-increment field or issuing a truncate command everynight. I also saw a few other creative solutions to prevent the auto increment.
However I prefer not to manage a side effect. I decided to try resolve this by using a different approach. Especially since the is a read and updatecentric table.
Revised approach
$lastInsertId=0;
$q->beginTransaction();
$sql = 'UPDATE data_snapshots SET field1=:field1,field2=:field2,field3=:field3,id = LAST_INSERT_ID(id) WHERE groupId=:groupId';
$args=[':groupId'=>$groupId,':field1'=>$field1,':field2'=>$field2,':field3'=>$field3];
$q->prepare ( $sql );
$result = $q->execute ( $args );
$lastInsertId = $q->lastInsertId();
if($lastInsertId == 0){
$sql='INSERT INTO data_snapshots (groupId,field1,field2,field3)';
$q->prepare ( $sql );
$result = $q->execute ( $args );
$lastInsertId = $q->lastInsertId();
}
if($result == true && $lastInsertId > 0){
$q->commit();
$modified=true;
}
else{
$q->rollBack();
}
Upsert approach
$sql='INSERT INTO data_snapshots
(groupId,field1,field2,field3)
VALUES
(:groupId,:field1,:field2,:field3)
ON DUPLICATE KEY UPDATE
groupId=:groupId_dup,field1=:field1_dup,field2=:field2_dup,field3=:field3_dup'];
$args=[':groupId'=>$groupId,':field1'=>$field1,':field2'=>$field2,':field3'=>$field3,
':groupId_dup'=>$groupId,':field1_dup'=>$field1,':field2_dup'=>$field2,':field3_dup'=>$field3,]
$q->prepare ( $sql );
$result = $q->execute ( $args );