Is this a good way to move items on update to a different table?
So i have a table 'fruits', which has 2 stage deletion process with first being a soft deletion and the second being a hard deletion that deletes item at various times based on business rules.
This table is performing badly when there are large number of rows, easiest way seemed to be to delete all the fruits marked for deletion and the UI performance is restored almost immediately.
While partitioning fruits on the 'deleted' column would be a great idea, we cant do it because we have 3 Foreign key constraints that prevents from using the built-in partitioning flow.
So the idea was to simulate partitioning by hooking a BEFORE UPDATE trigger to check if the updated row marks the row for deletion(soft) then do an INSERT into the 'fruits_deleted' table and DELETE the row that was due for UPDATE.
Currently the fruits table is only UPDATE'd to mark items for deletion. Nevertheless the trigger has a condition to check for operations specifically setting deleted=true.
Now i want to be sure that doing this is alright.Esp, in terms of the insert and delete happening without issues with the insert and delete being separate ops.
Should i wrap the concerned UPDATE calls in a transaction ?
Or should i leave it as is, considering that the row is locked when the update is happening and assume that should do fine ?
CREATE FUNCTION move_deleted_fruits()
RETURNS TRIGGER AS $$
BEGIN
IF ( NEW.deleted = true ) THEN
INSERT INTO fruits_deleted col1,col2... VALUE (NEW.val1,NEW.val2....);
DELETE FROM fruits where _id = OLD._id;
RETURN NULL; -- prevent other triggers from firing on update that sets deleted=true.
ELSE
UPDATE fruits SET col1=val1,col2=val2... WHERE _id = OLD._id;
RETURN NEW.*;
END IF;
END;
$$
LANGUAGE plpgsql;
--and then
CREATE TRIGGER trig_move_deleted_fruits
BEFORE UPDATE ON fruits
FOR EACH ROW EXECUTE PROCEDURE move_deleted_fruits();
But indeed other ideas are welcome to do the isolation differently. There is a lot of complex queries (many of them inefficient and are marked for improvement as tech debt) but this is something that needs to be fixed as of now, as is.
postgresql postgresql-9.4
New contributor
add a comment |
So i have a table 'fruits', which has 2 stage deletion process with first being a soft deletion and the second being a hard deletion that deletes item at various times based on business rules.
This table is performing badly when there are large number of rows, easiest way seemed to be to delete all the fruits marked for deletion and the UI performance is restored almost immediately.
While partitioning fruits on the 'deleted' column would be a great idea, we cant do it because we have 3 Foreign key constraints that prevents from using the built-in partitioning flow.
So the idea was to simulate partitioning by hooking a BEFORE UPDATE trigger to check if the updated row marks the row for deletion(soft) then do an INSERT into the 'fruits_deleted' table and DELETE the row that was due for UPDATE.
Currently the fruits table is only UPDATE'd to mark items for deletion. Nevertheless the trigger has a condition to check for operations specifically setting deleted=true.
Now i want to be sure that doing this is alright.Esp, in terms of the insert and delete happening without issues with the insert and delete being separate ops.
Should i wrap the concerned UPDATE calls in a transaction ?
Or should i leave it as is, considering that the row is locked when the update is happening and assume that should do fine ?
CREATE FUNCTION move_deleted_fruits()
RETURNS TRIGGER AS $$
BEGIN
IF ( NEW.deleted = true ) THEN
INSERT INTO fruits_deleted col1,col2... VALUE (NEW.val1,NEW.val2....);
DELETE FROM fruits where _id = OLD._id;
RETURN NULL; -- prevent other triggers from firing on update that sets deleted=true.
ELSE
UPDATE fruits SET col1=val1,col2=val2... WHERE _id = OLD._id;
RETURN NEW.*;
END IF;
END;
$$
LANGUAGE plpgsql;
--and then
CREATE TRIGGER trig_move_deleted_fruits
BEFORE UPDATE ON fruits
FOR EACH ROW EXECUTE PROCEDURE move_deleted_fruits();
But indeed other ideas are welcome to do the isolation differently. There is a lot of complex queries (many of them inefficient and are marked for improvement as tech debt) but this is something that needs to be fixed as of now, as is.
postgresql postgresql-9.4
New contributor
add a comment |
So i have a table 'fruits', which has 2 stage deletion process with first being a soft deletion and the second being a hard deletion that deletes item at various times based on business rules.
This table is performing badly when there are large number of rows, easiest way seemed to be to delete all the fruits marked for deletion and the UI performance is restored almost immediately.
While partitioning fruits on the 'deleted' column would be a great idea, we cant do it because we have 3 Foreign key constraints that prevents from using the built-in partitioning flow.
So the idea was to simulate partitioning by hooking a BEFORE UPDATE trigger to check if the updated row marks the row for deletion(soft) then do an INSERT into the 'fruits_deleted' table and DELETE the row that was due for UPDATE.
Currently the fruits table is only UPDATE'd to mark items for deletion. Nevertheless the trigger has a condition to check for operations specifically setting deleted=true.
Now i want to be sure that doing this is alright.Esp, in terms of the insert and delete happening without issues with the insert and delete being separate ops.
Should i wrap the concerned UPDATE calls in a transaction ?
Or should i leave it as is, considering that the row is locked when the update is happening and assume that should do fine ?
CREATE FUNCTION move_deleted_fruits()
RETURNS TRIGGER AS $$
BEGIN
IF ( NEW.deleted = true ) THEN
INSERT INTO fruits_deleted col1,col2... VALUE (NEW.val1,NEW.val2....);
DELETE FROM fruits where _id = OLD._id;
RETURN NULL; -- prevent other triggers from firing on update that sets deleted=true.
ELSE
UPDATE fruits SET col1=val1,col2=val2... WHERE _id = OLD._id;
RETURN NEW.*;
END IF;
END;
$$
LANGUAGE plpgsql;
--and then
CREATE TRIGGER trig_move_deleted_fruits
BEFORE UPDATE ON fruits
FOR EACH ROW EXECUTE PROCEDURE move_deleted_fruits();
But indeed other ideas are welcome to do the isolation differently. There is a lot of complex queries (many of them inefficient and are marked for improvement as tech debt) but this is something that needs to be fixed as of now, as is.
postgresql postgresql-9.4
New contributor
So i have a table 'fruits', which has 2 stage deletion process with first being a soft deletion and the second being a hard deletion that deletes item at various times based on business rules.
This table is performing badly when there are large number of rows, easiest way seemed to be to delete all the fruits marked for deletion and the UI performance is restored almost immediately.
While partitioning fruits on the 'deleted' column would be a great idea, we cant do it because we have 3 Foreign key constraints that prevents from using the built-in partitioning flow.
So the idea was to simulate partitioning by hooking a BEFORE UPDATE trigger to check if the updated row marks the row for deletion(soft) then do an INSERT into the 'fruits_deleted' table and DELETE the row that was due for UPDATE.
Currently the fruits table is only UPDATE'd to mark items for deletion. Nevertheless the trigger has a condition to check for operations specifically setting deleted=true.
Now i want to be sure that doing this is alright.Esp, in terms of the insert and delete happening without issues with the insert and delete being separate ops.
Should i wrap the concerned UPDATE calls in a transaction ?
Or should i leave it as is, considering that the row is locked when the update is happening and assume that should do fine ?
CREATE FUNCTION move_deleted_fruits()
RETURNS TRIGGER AS $$
BEGIN
IF ( NEW.deleted = true ) THEN
INSERT INTO fruits_deleted col1,col2... VALUE (NEW.val1,NEW.val2....);
DELETE FROM fruits where _id = OLD._id;
RETURN NULL; -- prevent other triggers from firing on update that sets deleted=true.
ELSE
UPDATE fruits SET col1=val1,col2=val2... WHERE _id = OLD._id;
RETURN NEW.*;
END IF;
END;
$$
LANGUAGE plpgsql;
--and then
CREATE TRIGGER trig_move_deleted_fruits
BEFORE UPDATE ON fruits
FOR EACH ROW EXECUTE PROCEDURE move_deleted_fruits();
But indeed other ideas are welcome to do the isolation differently. There is a lot of complex queries (many of them inefficient and are marked for improvement as tech debt) but this is something that needs to be fixed as of now, as is.
postgresql postgresql-9.4
postgresql postgresql-9.4
New contributor
New contributor
edited 1 min ago
Naresh Kumar
New contributor
asked 10 mins ago
Naresh KumarNaresh Kumar
1011
1011
New contributor
New contributor
add a comment |
add a comment |
0
active
oldest
votes
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "182"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Naresh Kumar is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f229376%2fis-this-a-good-way-to-move-items-on-update-to-a-different-table%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
0
active
oldest
votes
0
active
oldest
votes
active
oldest
votes
active
oldest
votes
Naresh Kumar is a new contributor. Be nice, and check out our Code of Conduct.
Naresh Kumar is a new contributor. Be nice, and check out our Code of Conduct.
Naresh Kumar is a new contributor. Be nice, and check out our Code of Conduct.
Naresh Kumar is a new contributor. Be nice, and check out our Code of Conduct.
Thanks for contributing an answer to Database Administrators Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f229376%2fis-this-a-good-way-to-move-items-on-update-to-a-different-table%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown