What is the appropriate index architecture when forced to implement IsDeleted (soft deletes)? ...
Converted a Scalar function to a TVF function for parallel execution-Still running in Serial mode
How come Sam didn't become Lord of Horn Hill?
How does light 'choose' between wave and particle behaviour?
How to react to hostile behavior from a senior developer?
Morning, Afternoon, Night Kanji
What does it mean that physics no longer uses mechanical models to describe phenomena?
Significance of Cersei's obsession with elephants?
Is there any word for a place full of confusion?
Find 108 by using 3,4,6
Time to Settle Down!
Why do early math courses focus on the cross sections of a cone and not on other 3D objects?
Did Deadpool rescue all of the X-Force?
Is it fair for a professor to grade us on the possession of past papers?
Is there a kind of relay only consumes power when switching?
Why should I vote and accept answers?
Why do we bend a book to keep it straight?
Generate an RGB colour grid
Is grep documentation about ignoring case wrong, since it doesn't ignore case in filenames?
What is the appropriate index architecture when forced to implement IsDeleted (soft deletes)?
Did Krishna say in Bhagavad Gita "I am in every living being"
Why weren't discrete x86 CPUs ever used in game hardware?
How fail-safe is nr as stop bytes?
Selecting user stories during sprint planning
Most bit efficient text communication method?
What is the appropriate index architecture when forced to implement IsDeleted (soft deletes)?
Announcing the arrival of Valued Associate #679: Cesar Manara
Planned maintenance scheduled April 23, 2019 at 00:00UTC (8:00pm US/Eastern)Can filtered indexes help improve queries that are based on a time entered or should this be avoided?Clustered vs Nonclustered IndexUnused Indexes - Consider Primary Key Constraint Supporting Indexes?Question about non-clustered index storage in SQL ServerIndex not making execution faster, and in some cases is slowing down the query. Why is it so?Should I remove this clustered index?what if all the non clustered indexes on my table were filtered indexes?What is the formal definition of a Primary Index and Primary Key?Would a nonclustered index on the primary key speed up deletes and prevent deadlocks?When all you indexes have included all the other columns, do you still have the penalty for a wide clustered index?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ margin-bottom:0;
}
Currently, we have an existing database and application that is fully functional. I do not have the ability to change the architecture at this point. Today, each table in the database has an "IsDeleted" NOT NULL BIT field with a default of '0'. When the application "deletes" data, it simply updates the IsDeleted flag to 1.
What I'm having trouble understanding is how the indexes on each of the tables should be structured. Right now, every query/join/etc always implements the IsDeleted check. It's a standard that our developers must follow. That being said, I'm trying to determine if all of my clustered primary key indexes on each of the tables need to be altered to include the primary key AND the IsDeleted BIT field. Also, since EVERY query/join/etc. must implement the IsDeleted check, is it an appropriate assumption that EVERY SINGLE index (non-clustered as well) should include the IsDeleted field as the first field of the index?
One other question I have is around filtered indexes. I understand that I could put filters on the indexes such as "WHERE IsDeleted = 0" to reduce the size of the indexes. However, since every join/query will have to implement the IsDeleted check, would that prevent the filtered index from being used (since the IsDeleted column is used in join/query)?
Remember, I do not have the ability to change the IsDeleted approach.
sql-server sql-server-2012 index
migrated from serverfault.com 12 hours ago
This question came from our site for system and network administrators.
add a comment |
Currently, we have an existing database and application that is fully functional. I do not have the ability to change the architecture at this point. Today, each table in the database has an "IsDeleted" NOT NULL BIT field with a default of '0'. When the application "deletes" data, it simply updates the IsDeleted flag to 1.
What I'm having trouble understanding is how the indexes on each of the tables should be structured. Right now, every query/join/etc always implements the IsDeleted check. It's a standard that our developers must follow. That being said, I'm trying to determine if all of my clustered primary key indexes on each of the tables need to be altered to include the primary key AND the IsDeleted BIT field. Also, since EVERY query/join/etc. must implement the IsDeleted check, is it an appropriate assumption that EVERY SINGLE index (non-clustered as well) should include the IsDeleted field as the first field of the index?
One other question I have is around filtered indexes. I understand that I could put filters on the indexes such as "WHERE IsDeleted = 0" to reduce the size of the indexes. However, since every join/query will have to implement the IsDeleted check, would that prevent the filtered index from being used (since the IsDeleted column is used in join/query)?
Remember, I do not have the ability to change the IsDeleted approach.
sql-server sql-server-2012 index
migrated from serverfault.com 12 hours ago
This question came from our site for system and network administrators.
5
A big component of the architecture decision is the rough percentage of rows that will match IsDeleted = 0. If you're just now implementing it, and hardly any of the rows will have IsDeleted = 1 yet, then you don't have to worry nearly as much about it as, say, a 10-year-old system where 75% of the rows have IsDeleted = 1.
– Brent Ozar
13 hours ago
Whilst not part of the question, I hope you don't have any 'users' in your system. a 'soft delete' function will likely not be acceptable in the post GDPR world.
– Neil
5 hours ago
add a comment |
Currently, we have an existing database and application that is fully functional. I do not have the ability to change the architecture at this point. Today, each table in the database has an "IsDeleted" NOT NULL BIT field with a default of '0'. When the application "deletes" data, it simply updates the IsDeleted flag to 1.
What I'm having trouble understanding is how the indexes on each of the tables should be structured. Right now, every query/join/etc always implements the IsDeleted check. It's a standard that our developers must follow. That being said, I'm trying to determine if all of my clustered primary key indexes on each of the tables need to be altered to include the primary key AND the IsDeleted BIT field. Also, since EVERY query/join/etc. must implement the IsDeleted check, is it an appropriate assumption that EVERY SINGLE index (non-clustered as well) should include the IsDeleted field as the first field of the index?
One other question I have is around filtered indexes. I understand that I could put filters on the indexes such as "WHERE IsDeleted = 0" to reduce the size of the indexes. However, since every join/query will have to implement the IsDeleted check, would that prevent the filtered index from being used (since the IsDeleted column is used in join/query)?
Remember, I do not have the ability to change the IsDeleted approach.
sql-server sql-server-2012 index
Currently, we have an existing database and application that is fully functional. I do not have the ability to change the architecture at this point. Today, each table in the database has an "IsDeleted" NOT NULL BIT field with a default of '0'. When the application "deletes" data, it simply updates the IsDeleted flag to 1.
What I'm having trouble understanding is how the indexes on each of the tables should be structured. Right now, every query/join/etc always implements the IsDeleted check. It's a standard that our developers must follow. That being said, I'm trying to determine if all of my clustered primary key indexes on each of the tables need to be altered to include the primary key AND the IsDeleted BIT field. Also, since EVERY query/join/etc. must implement the IsDeleted check, is it an appropriate assumption that EVERY SINGLE index (non-clustered as well) should include the IsDeleted field as the first field of the index?
One other question I have is around filtered indexes. I understand that I could put filters on the indexes such as "WHERE IsDeleted = 0" to reduce the size of the indexes. However, since every join/query will have to implement the IsDeleted check, would that prevent the filtered index from being used (since the IsDeleted column is used in join/query)?
Remember, I do not have the ability to change the IsDeleted approach.
sql-server sql-server-2012 index
sql-server sql-server-2012 index
edited 12 hours ago
Philᵀᴹ
25.8k65591
25.8k65591
asked 13 hours ago
Jerad Skinner
migrated from serverfault.com 12 hours ago
This question came from our site for system and network administrators.
migrated from serverfault.com 12 hours ago
This question came from our site for system and network administrators.
5
A big component of the architecture decision is the rough percentage of rows that will match IsDeleted = 0. If you're just now implementing it, and hardly any of the rows will have IsDeleted = 1 yet, then you don't have to worry nearly as much about it as, say, a 10-year-old system where 75% of the rows have IsDeleted = 1.
– Brent Ozar
13 hours ago
Whilst not part of the question, I hope you don't have any 'users' in your system. a 'soft delete' function will likely not be acceptable in the post GDPR world.
– Neil
5 hours ago
add a comment |
5
A big component of the architecture decision is the rough percentage of rows that will match IsDeleted = 0. If you're just now implementing it, and hardly any of the rows will have IsDeleted = 1 yet, then you don't have to worry nearly as much about it as, say, a 10-year-old system where 75% of the rows have IsDeleted = 1.
– Brent Ozar
13 hours ago
Whilst not part of the question, I hope you don't have any 'users' in your system. a 'soft delete' function will likely not be acceptable in the post GDPR world.
– Neil
5 hours ago
5
5
A big component of the architecture decision is the rough percentage of rows that will match IsDeleted = 0. If you're just now implementing it, and hardly any of the rows will have IsDeleted = 1 yet, then you don't have to worry nearly as much about it as, say, a 10-year-old system where 75% of the rows have IsDeleted = 1.
– Brent Ozar
13 hours ago
A big component of the architecture decision is the rough percentage of rows that will match IsDeleted = 0. If you're just now implementing it, and hardly any of the rows will have IsDeleted = 1 yet, then you don't have to worry nearly as much about it as, say, a 10-year-old system where 75% of the rows have IsDeleted = 1.
– Brent Ozar
13 hours ago
Whilst not part of the question, I hope you don't have any 'users' in your system. a 'soft delete' function will likely not be acceptable in the post GDPR world.
– Neil
5 hours ago
Whilst not part of the question, I hope you don't have any 'users' in your system. a 'soft delete' function will likely not be acceptable in the post GDPR world.
– Neil
5 hours ago
add a comment |
3 Answers
3
active
oldest
votes
The easiest approach here is to leave your keys and clustered indexes alone, and use filtered indexes for your non-clustered indexes.
Additionally you can migrate some large tables to partitioned heaps or partitioned clustered-columnstores (SQL Server 2016+), leaving the primary key and unique indexes un-partitioned. This would enable you to push the non-key columns for IsDeleted rows to a seperate data structure, which could additionally be compressed differently or stored on a different filegroup.
And make sure the developers use a literal instead of a parameter to filter the IsDeleted rows out. With a parameter SQL Server has to use the same query plan for both cases.
EG
SELECT ... WHERE ... AND IsDeleted=0
And not:
SELECT ... WHERE ... AND IsDeleted=@IsDeleted
Using a paramter will prevent use of filtered index, and can get you into trouble with parameter sniffing.
add a comment |
This might be an unpopular opinion, but I don't think there is a "do this everywhere" / one size fits all answer to your question.
If you have queries that are scanning lots of IsDeleted rows for no reason, one solution is to create a filtered, nonclustered index to satisfy that query.
Another option is to create an indexed view that could be leveraged by a number of different queries, which is filtered to just the non-deleted rows. This could be especially useful on Enterprise Edition, where automatic indexed view matching works without providing a NOEXPAND
hint.
For small tables, or tables that are read heavily, adding filtered nonclustered indexes or views or anything really might just be adding unnecessary overhead to your database.
add a comment |
Under the reasonable assumption that deletes are rare, no changes to the indices is an appropriate solution.
I found that sooner or later one must query for references to deleted rows, and the rows being in the indices is suddenly very worth it.
Please note that unless you are using views, you have to edit all of your queries to include the filters anyway.
add a comment |
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
});
}
});
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%2f235169%2fwhat-is-the-appropriate-index-architecture-when-forced-to-implement-isdeleted-s%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
The easiest approach here is to leave your keys and clustered indexes alone, and use filtered indexes for your non-clustered indexes.
Additionally you can migrate some large tables to partitioned heaps or partitioned clustered-columnstores (SQL Server 2016+), leaving the primary key and unique indexes un-partitioned. This would enable you to push the non-key columns for IsDeleted rows to a seperate data structure, which could additionally be compressed differently or stored on a different filegroup.
And make sure the developers use a literal instead of a parameter to filter the IsDeleted rows out. With a parameter SQL Server has to use the same query plan for both cases.
EG
SELECT ... WHERE ... AND IsDeleted=0
And not:
SELECT ... WHERE ... AND IsDeleted=@IsDeleted
Using a paramter will prevent use of filtered index, and can get you into trouble with parameter sniffing.
add a comment |
The easiest approach here is to leave your keys and clustered indexes alone, and use filtered indexes for your non-clustered indexes.
Additionally you can migrate some large tables to partitioned heaps or partitioned clustered-columnstores (SQL Server 2016+), leaving the primary key and unique indexes un-partitioned. This would enable you to push the non-key columns for IsDeleted rows to a seperate data structure, which could additionally be compressed differently or stored on a different filegroup.
And make sure the developers use a literal instead of a parameter to filter the IsDeleted rows out. With a parameter SQL Server has to use the same query plan for both cases.
EG
SELECT ... WHERE ... AND IsDeleted=0
And not:
SELECT ... WHERE ... AND IsDeleted=@IsDeleted
Using a paramter will prevent use of filtered index, and can get you into trouble with parameter sniffing.
add a comment |
The easiest approach here is to leave your keys and clustered indexes alone, and use filtered indexes for your non-clustered indexes.
Additionally you can migrate some large tables to partitioned heaps or partitioned clustered-columnstores (SQL Server 2016+), leaving the primary key and unique indexes un-partitioned. This would enable you to push the non-key columns for IsDeleted rows to a seperate data structure, which could additionally be compressed differently or stored on a different filegroup.
And make sure the developers use a literal instead of a parameter to filter the IsDeleted rows out. With a parameter SQL Server has to use the same query plan for both cases.
EG
SELECT ... WHERE ... AND IsDeleted=0
And not:
SELECT ... WHERE ... AND IsDeleted=@IsDeleted
Using a paramter will prevent use of filtered index, and can get you into trouble with parameter sniffing.
The easiest approach here is to leave your keys and clustered indexes alone, and use filtered indexes for your non-clustered indexes.
Additionally you can migrate some large tables to partitioned heaps or partitioned clustered-columnstores (SQL Server 2016+), leaving the primary key and unique indexes un-partitioned. This would enable you to push the non-key columns for IsDeleted rows to a seperate data structure, which could additionally be compressed differently or stored on a different filegroup.
And make sure the developers use a literal instead of a parameter to filter the IsDeleted rows out. With a parameter SQL Server has to use the same query plan for both cases.
EG
SELECT ... WHERE ... AND IsDeleted=0
And not:
SELECT ... WHERE ... AND IsDeleted=@IsDeleted
Using a paramter will prevent use of filtered index, and can get you into trouble with parameter sniffing.
edited 5 hours ago
answered 11 hours ago
David Browne - MicrosoftDavid Browne - Microsoft
12.5k729
12.5k729
add a comment |
add a comment |
This might be an unpopular opinion, but I don't think there is a "do this everywhere" / one size fits all answer to your question.
If you have queries that are scanning lots of IsDeleted rows for no reason, one solution is to create a filtered, nonclustered index to satisfy that query.
Another option is to create an indexed view that could be leveraged by a number of different queries, which is filtered to just the non-deleted rows. This could be especially useful on Enterprise Edition, where automatic indexed view matching works without providing a NOEXPAND
hint.
For small tables, or tables that are read heavily, adding filtered nonclustered indexes or views or anything really might just be adding unnecessary overhead to your database.
add a comment |
This might be an unpopular opinion, but I don't think there is a "do this everywhere" / one size fits all answer to your question.
If you have queries that are scanning lots of IsDeleted rows for no reason, one solution is to create a filtered, nonclustered index to satisfy that query.
Another option is to create an indexed view that could be leveraged by a number of different queries, which is filtered to just the non-deleted rows. This could be especially useful on Enterprise Edition, where automatic indexed view matching works without providing a NOEXPAND
hint.
For small tables, or tables that are read heavily, adding filtered nonclustered indexes or views or anything really might just be adding unnecessary overhead to your database.
add a comment |
This might be an unpopular opinion, but I don't think there is a "do this everywhere" / one size fits all answer to your question.
If you have queries that are scanning lots of IsDeleted rows for no reason, one solution is to create a filtered, nonclustered index to satisfy that query.
Another option is to create an indexed view that could be leveraged by a number of different queries, which is filtered to just the non-deleted rows. This could be especially useful on Enterprise Edition, where automatic indexed view matching works without providing a NOEXPAND
hint.
For small tables, or tables that are read heavily, adding filtered nonclustered indexes or views or anything really might just be adding unnecessary overhead to your database.
This might be an unpopular opinion, but I don't think there is a "do this everywhere" / one size fits all answer to your question.
If you have queries that are scanning lots of IsDeleted rows for no reason, one solution is to create a filtered, nonclustered index to satisfy that query.
Another option is to create an indexed view that could be leveraged by a number of different queries, which is filtered to just the non-deleted rows. This could be especially useful on Enterprise Edition, where automatic indexed view matching works without providing a NOEXPAND
hint.
For small tables, or tables that are read heavily, adding filtered nonclustered indexes or views or anything really might just be adding unnecessary overhead to your database.
answered 11 hours ago
Josh DarnellJosh Darnell
8,31922243
8,31922243
add a comment |
add a comment |
Under the reasonable assumption that deletes are rare, no changes to the indices is an appropriate solution.
I found that sooner or later one must query for references to deleted rows, and the rows being in the indices is suddenly very worth it.
Please note that unless you are using views, you have to edit all of your queries to include the filters anyway.
add a comment |
Under the reasonable assumption that deletes are rare, no changes to the indices is an appropriate solution.
I found that sooner or later one must query for references to deleted rows, and the rows being in the indices is suddenly very worth it.
Please note that unless you are using views, you have to edit all of your queries to include the filters anyway.
add a comment |
Under the reasonable assumption that deletes are rare, no changes to the indices is an appropriate solution.
I found that sooner or later one must query for references to deleted rows, and the rows being in the indices is suddenly very worth it.
Please note that unless you are using views, you have to edit all of your queries to include the filters anyway.
Under the reasonable assumption that deletes are rare, no changes to the indices is an appropriate solution.
I found that sooner or later one must query for references to deleted rows, and the rows being in the indices is suddenly very worth it.
Please note that unless you are using views, you have to edit all of your queries to include the filters anyway.
answered 9 hours ago
JoshuaJoshua
1536
1536
add a comment |
add a comment |
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%2f235169%2fwhat-is-the-appropriate-index-architecture-when-forced-to-implement-isdeleted-s%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
5
A big component of the architecture decision is the rough percentage of rows that will match IsDeleted = 0. If you're just now implementing it, and hardly any of the rows will have IsDeleted = 1 yet, then you don't have to worry nearly as much about it as, say, a 10-year-old system where 75% of the rows have IsDeleted = 1.
– Brent Ozar
13 hours ago
Whilst not part of the question, I hope you don't have any 'users' in your system. a 'soft delete' function will likely not be acceptable in the post GDPR world.
– Neil
5 hours ago