What is the appropriate index architecture when forced to implement IsDeleted (soft deletes)?Key Lookup and Full-text indexClustered 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 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?

Why is coffee provided during big chess events when it contains a banned substance?

Little Endian Number to String Conversion

70's/80's story about a high ranking prisoner of war on a prison planet

Why is it so hard to land on the Moon?

Multiple stock symbols for same company with in USA

Is this an error...?

What is this dial on my old film camera for?

What causes standard door hinges to close up to a certain amount automatically?

5v home network

Match the blocks

An employee has low self-confidence, and is performing poorly. How can I help?

What can I do to avoid potential charges for bribery?

What does IKEA-like mean?

Is it possible to do a low carb diet for a month in Sicily?

UK PM is taking his proposal to EU but has not proposed to his own parliament - can he legally bypass the UK parliament?

Does these arithmetic means on Pythagorean triangles converge?

Why did the range based for loop specification change in C++17

Does Australia produce unique 'specialty steel'?

Is data science mathematically interesting?

I didn't do any exit passport control when leaving Japan. What should I do?

Why is CMYK & PNG not possible?

Paper accepted at a probably predatory conference, how shall I proceed?

How honest to be with US immigration about uncertainty about travel plans?

How do you translate "Don't Fear the Reaper" into Latin?



What is the appropriate index architecture when forced to implement IsDeleted (soft deletes)?


Key Lookup and Full-text indexClustered 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 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;









16

















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.










share|improve this question


















migrated from serverfault.com Apr 18 at 14:11


This question came from our site for system and network administrators.

























    16

















    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.










    share|improve this question


















    migrated from serverfault.com Apr 18 at 14:11


    This question came from our site for system and network administrators.





















      16












      16








      16


      1






      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.










      share|improve this question
















      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






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question



      share|improve this question








      edited Apr 18 at 14:17









      Philᵀᴹ

      27.3k6 gold badges60 silver badges94 bronze badges




      27.3k6 gold badges60 silver badges94 bronze badges










      asked Apr 18 at 13:24







      Jerad Skinner












      migrated from serverfault.com Apr 18 at 14:11


      This question came from our site for system and network administrators.











      migrated from serverfault.com Apr 18 at 14:11


      This question came from our site for system and network administrators.









      migrated from serverfault.com Apr 18 at 14:11


      This question came from our site for system and network administrators.






















          5 Answers
          5






          active

          oldest

          votes


















          13


















          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.






          share|improve this answer




























          • Given the ubiquity and importance of the IsDeleted column, regardless of the physical storage it would probably make sense to expose the data through two views (optionally in different schemas), solving both the parameterization issue and making mistakes with accessing data that shouldn't have been accessed less likely. Accessing the base data is only relevant for the rare cases where deleted and non-deleted data need to be combined somehow, and when rows actually need to be switched to "deleted".

            – Jeroen Mostert
            Apr 19 at 11:29











          • @JeroenMostert good advice. RLS can also be used here, or something like EF Core Global Query Filters. docs.microsoft.com/en-us/ef/core/querying/filters

            – David Browne - Microsoft
            Apr 19 at 12:17


















          9


















          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.






          share|improve this answer

































            2


















            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.






            share|improve this answer

































              0


















              I have seen a system where the IS_DELETED flag is either 0 or the value of the PK. In other systems it was the negative of the PK.



              Since most queries retrieved values by the "natural" or business (sometimes multi-field) key, they never queried by PK except through joins; but they did always add an AND IS_DELETED = 0 at the end for the main table and for any joined tables.



              This system also had an audit table for every transactional table that tracked changes; and the application had a feature to display all the data changes including the deleted data.






              share|improve this answer

































                0


















                Hope you have right and ability to change query.




                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)?




                I wanted to say one important point,hope i am able to explain it.



                In complex query where Transaction table and Master tables both are use.



                Use IsDeleted=0 only in Transaction table.
                Do not use in Master table.



                Example,



                Select * from dbo.Order O
                inner join dbo.category C on o.categoryid=o.categoryid
                inner join dbo.Product P on P.Productid=o.Productid
                where o.isdeleted=0


                There is no point in c.isdeleted=0 (using in Category table).It is unnecessary.



                Similarly is there any point in using P.isdeleted=0 ?



                Because I want all undeleted Order and their details.



                How can Product be deleted when Order is Active or wherever Productid is reference.



                So this way if you debug carefully in important query, then may be you can remove some of the isdeleted=0.



                Don't blindly Create Filtered Index, first select all those very important and slow query.



                Optimize those slow query then only decide about Filtered Index or tune Index.






                share|improve this answer



























                  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/4.0/"u003ecc by-sa 4.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
                  );



                  );














                  draft saved

                  draft discarded
















                  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

























                  5 Answers
                  5






                  active

                  oldest

                  votes








                  5 Answers
                  5






                  active

                  oldest

                  votes









                  active

                  oldest

                  votes






                  active

                  oldest

                  votes









                  13


















                  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.






                  share|improve this answer




























                  • Given the ubiquity and importance of the IsDeleted column, regardless of the physical storage it would probably make sense to expose the data through two views (optionally in different schemas), solving both the parameterization issue and making mistakes with accessing data that shouldn't have been accessed less likely. Accessing the base data is only relevant for the rare cases where deleted and non-deleted data need to be combined somehow, and when rows actually need to be switched to "deleted".

                    – Jeroen Mostert
                    Apr 19 at 11:29











                  • @JeroenMostert good advice. RLS can also be used here, or something like EF Core Global Query Filters. docs.microsoft.com/en-us/ef/core/querying/filters

                    – David Browne - Microsoft
                    Apr 19 at 12:17















                  13


















                  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.






                  share|improve this answer




























                  • Given the ubiquity and importance of the IsDeleted column, regardless of the physical storage it would probably make sense to expose the data through two views (optionally in different schemas), solving both the parameterization issue and making mistakes with accessing data that shouldn't have been accessed less likely. Accessing the base data is only relevant for the rare cases where deleted and non-deleted data need to be combined somehow, and when rows actually need to be switched to "deleted".

                    – Jeroen Mostert
                    Apr 19 at 11:29











                  • @JeroenMostert good advice. RLS can also be used here, or something like EF Core Global Query Filters. docs.microsoft.com/en-us/ef/core/querying/filters

                    – David Browne - Microsoft
                    Apr 19 at 12:17













                  13














                  13










                  13









                  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.






                  share|improve this answer
















                  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.







                  share|improve this answer















                  share|improve this answer




                  share|improve this answer



                  share|improve this answer








                  edited Apr 18 at 20:53

























                  answered Apr 18 at 14:48









                  David Browne - MicrosoftDavid Browne - Microsoft

                  15.9k1 gold badge14 silver badges42 bronze badges




                  15.9k1 gold badge14 silver badges42 bronze badges















                  • Given the ubiquity and importance of the IsDeleted column, regardless of the physical storage it would probably make sense to expose the data through two views (optionally in different schemas), solving both the parameterization issue and making mistakes with accessing data that shouldn't have been accessed less likely. Accessing the base data is only relevant for the rare cases where deleted and non-deleted data need to be combined somehow, and when rows actually need to be switched to "deleted".

                    – Jeroen Mostert
                    Apr 19 at 11:29











                  • @JeroenMostert good advice. RLS can also be used here, or something like EF Core Global Query Filters. docs.microsoft.com/en-us/ef/core/querying/filters

                    – David Browne - Microsoft
                    Apr 19 at 12:17

















                  • Given the ubiquity and importance of the IsDeleted column, regardless of the physical storage it would probably make sense to expose the data through two views (optionally in different schemas), solving both the parameterization issue and making mistakes with accessing data that shouldn't have been accessed less likely. Accessing the base data is only relevant for the rare cases where deleted and non-deleted data need to be combined somehow, and when rows actually need to be switched to "deleted".

                    – Jeroen Mostert
                    Apr 19 at 11:29











                  • @JeroenMostert good advice. RLS can also be used here, or something like EF Core Global Query Filters. docs.microsoft.com/en-us/ef/core/querying/filters

                    – David Browne - Microsoft
                    Apr 19 at 12:17
















                  Given the ubiquity and importance of the IsDeleted column, regardless of the physical storage it would probably make sense to expose the data through two views (optionally in different schemas), solving both the parameterization issue and making mistakes with accessing data that shouldn't have been accessed less likely. Accessing the base data is only relevant for the rare cases where deleted and non-deleted data need to be combined somehow, and when rows actually need to be switched to "deleted".

                  – Jeroen Mostert
                  Apr 19 at 11:29





                  Given the ubiquity and importance of the IsDeleted column, regardless of the physical storage it would probably make sense to expose the data through two views (optionally in different schemas), solving both the parameterization issue and making mistakes with accessing data that shouldn't have been accessed less likely. Accessing the base data is only relevant for the rare cases where deleted and non-deleted data need to be combined somehow, and when rows actually need to be switched to "deleted".

                  – Jeroen Mostert
                  Apr 19 at 11:29













                  @JeroenMostert good advice. RLS can also be used here, or something like EF Core Global Query Filters. docs.microsoft.com/en-us/ef/core/querying/filters

                  – David Browne - Microsoft
                  Apr 19 at 12:17





                  @JeroenMostert good advice. RLS can also be used here, or something like EF Core Global Query Filters. docs.microsoft.com/en-us/ef/core/querying/filters

                  – David Browne - Microsoft
                  Apr 19 at 12:17













                  9


















                  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.






                  share|improve this answer






























                    9


















                    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.






                    share|improve this answer




























                      9














                      9










                      9









                      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.






                      share|improve this answer














                      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.







                      share|improve this answer













                      share|improve this answer




                      share|improve this answer



                      share|improve this answer










                      answered Apr 18 at 14:52









                      Josh DarnellJosh Darnell

                      13.7k4 gold badges31 silver badges64 bronze badges




                      13.7k4 gold badges31 silver badges64 bronze badges
























                          2


















                          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.






                          share|improve this answer






























                            2


















                            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.






                            share|improve this answer




























                              2














                              2










                              2









                              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.






                              share|improve this answer














                              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.







                              share|improve this answer













                              share|improve this answer




                              share|improve this answer



                              share|improve this answer










                              answered Apr 18 at 17:03









                              JoshuaJoshua

                              1806 bronze badges




                              1806 bronze badges
























                                  0


















                                  I have seen a system where the IS_DELETED flag is either 0 or the value of the PK. In other systems it was the negative of the PK.



                                  Since most queries retrieved values by the "natural" or business (sometimes multi-field) key, they never queried by PK except through joins; but they did always add an AND IS_DELETED = 0 at the end for the main table and for any joined tables.



                                  This system also had an audit table for every transactional table that tracked changes; and the application had a feature to display all the data changes including the deleted data.






                                  share|improve this answer






























                                    0


















                                    I have seen a system where the IS_DELETED flag is either 0 or the value of the PK. In other systems it was the negative of the PK.



                                    Since most queries retrieved values by the "natural" or business (sometimes multi-field) key, they never queried by PK except through joins; but they did always add an AND IS_DELETED = 0 at the end for the main table and for any joined tables.



                                    This system also had an audit table for every transactional table that tracked changes; and the application had a feature to display all the data changes including the deleted data.






                                    share|improve this answer




























                                      0














                                      0










                                      0









                                      I have seen a system where the IS_DELETED flag is either 0 or the value of the PK. In other systems it was the negative of the PK.



                                      Since most queries retrieved values by the "natural" or business (sometimes multi-field) key, they never queried by PK except through joins; but they did always add an AND IS_DELETED = 0 at the end for the main table and for any joined tables.



                                      This system also had an audit table for every transactional table that tracked changes; and the application had a feature to display all the data changes including the deleted data.






                                      share|improve this answer














                                      I have seen a system where the IS_DELETED flag is either 0 or the value of the PK. In other systems it was the negative of the PK.



                                      Since most queries retrieved values by the "natural" or business (sometimes multi-field) key, they never queried by PK except through joins; but they did always add an AND IS_DELETED = 0 at the end for the main table and for any joined tables.



                                      This system also had an audit table for every transactional table that tracked changes; and the application had a feature to display all the data changes including the deleted data.







                                      share|improve this answer













                                      share|improve this answer




                                      share|improve this answer



                                      share|improve this answer










                                      answered Apr 19 at 4:31









                                      Rick RykerRick Ryker

                                      1413 bronze badges




                                      1413 bronze badges
























                                          0


















                                          Hope you have right and ability to change query.




                                          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)?




                                          I wanted to say one important point,hope i am able to explain it.



                                          In complex query where Transaction table and Master tables both are use.



                                          Use IsDeleted=0 only in Transaction table.
                                          Do not use in Master table.



                                          Example,



                                          Select * from dbo.Order O
                                          inner join dbo.category C on o.categoryid=o.categoryid
                                          inner join dbo.Product P on P.Productid=o.Productid
                                          where o.isdeleted=0


                                          There is no point in c.isdeleted=0 (using in Category table).It is unnecessary.



                                          Similarly is there any point in using P.isdeleted=0 ?



                                          Because I want all undeleted Order and their details.



                                          How can Product be deleted when Order is Active or wherever Productid is reference.



                                          So this way if you debug carefully in important query, then may be you can remove some of the isdeleted=0.



                                          Don't blindly Create Filtered Index, first select all those very important and slow query.



                                          Optimize those slow query then only decide about Filtered Index or tune Index.






                                          share|improve this answer






























                                            0


















                                            Hope you have right and ability to change query.




                                            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)?




                                            I wanted to say one important point,hope i am able to explain it.



                                            In complex query where Transaction table and Master tables both are use.



                                            Use IsDeleted=0 only in Transaction table.
                                            Do not use in Master table.



                                            Example,



                                            Select * from dbo.Order O
                                            inner join dbo.category C on o.categoryid=o.categoryid
                                            inner join dbo.Product P on P.Productid=o.Productid
                                            where o.isdeleted=0


                                            There is no point in c.isdeleted=0 (using in Category table).It is unnecessary.



                                            Similarly is there any point in using P.isdeleted=0 ?



                                            Because I want all undeleted Order and their details.



                                            How can Product be deleted when Order is Active or wherever Productid is reference.



                                            So this way if you debug carefully in important query, then may be you can remove some of the isdeleted=0.



                                            Don't blindly Create Filtered Index, first select all those very important and slow query.



                                            Optimize those slow query then only decide about Filtered Index or tune Index.






                                            share|improve this answer




























                                              0














                                              0










                                              0









                                              Hope you have right and ability to change query.




                                              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)?




                                              I wanted to say one important point,hope i am able to explain it.



                                              In complex query where Transaction table and Master tables both are use.



                                              Use IsDeleted=0 only in Transaction table.
                                              Do not use in Master table.



                                              Example,



                                              Select * from dbo.Order O
                                              inner join dbo.category C on o.categoryid=o.categoryid
                                              inner join dbo.Product P on P.Productid=o.Productid
                                              where o.isdeleted=0


                                              There is no point in c.isdeleted=0 (using in Category table).It is unnecessary.



                                              Similarly is there any point in using P.isdeleted=0 ?



                                              Because I want all undeleted Order and their details.



                                              How can Product be deleted when Order is Active or wherever Productid is reference.



                                              So this way if you debug carefully in important query, then may be you can remove some of the isdeleted=0.



                                              Don't blindly Create Filtered Index, first select all those very important and slow query.



                                              Optimize those slow query then only decide about Filtered Index or tune Index.






                                              share|improve this answer














                                              Hope you have right and ability to change query.




                                              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)?




                                              I wanted to say one important point,hope i am able to explain it.



                                              In complex query where Transaction table and Master tables both are use.



                                              Use IsDeleted=0 only in Transaction table.
                                              Do not use in Master table.



                                              Example,



                                              Select * from dbo.Order O
                                              inner join dbo.category C on o.categoryid=o.categoryid
                                              inner join dbo.Product P on P.Productid=o.Productid
                                              where o.isdeleted=0


                                              There is no point in c.isdeleted=0 (using in Category table).It is unnecessary.



                                              Similarly is there any point in using P.isdeleted=0 ?



                                              Because I want all undeleted Order and their details.



                                              How can Product be deleted when Order is Active or wherever Productid is reference.



                                              So this way if you debug carefully in important query, then may be you can remove some of the isdeleted=0.



                                              Don't blindly Create Filtered Index, first select all those very important and slow query.



                                              Optimize those slow query then only decide about Filtered Index or tune Index.







                                              share|improve this answer













                                              share|improve this answer




                                              share|improve this answer



                                              share|improve this answer










                                              answered Apr 26 at 11:35









                                              KumarHarshKumarHarsh

                                              1,1096 silver badges9 bronze badges




                                              1,1096 silver badges9 bronze badges































                                                  draft saved

                                                  draft discarded















































                                                  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.




                                                  draft saved


                                                  draft discarded














                                                  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





















































                                                  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









                                                  Popular posts from this blog

                                                  Tamil (spriik) Luke uk diar | Nawigatjuun

                                                  Align equal signs while including text over equalitiesAMS align: left aligned text/math plus multicolumn alignmentMultiple alignmentsAligning equations in multiple placesNumbering and aligning an equation with multiple columnsHow to align one equation with another multline equationUsing \ in environments inside the begintabularxNumber equations and preserving alignment of equal signsHow can I align equations to the left and to the right?Double equation alignment problem within align enviromentAligned within align: Why are they right-aligned?

                                                  Where does the image of a data connector as a sharp metal spike originate from?Where does the concept of infected people turning into zombies only after death originate from?Where does the motif of a reanimated human head originate?Where did the notion that Dragons could speak originate?Where does the archetypal image of the 'Grey' alien come from?Where did the suffix '-Man' originate?Where does the notion of being injured or killed by an illusion originate?Where did the term “sophont” originate?Where does the trope of magic spells being driven by advanced technology originate from?Where did the term “the living impaired” originate?