SQLskills SQL101: How can a SELECT cause a database to change?

As Kimberly blogged about recently, SQLskills is embarking on a new initiative to blog about basic topics, which we’re calling SQL101. We’ll all be blogging about things that we often see done incorrectly, technologies used the wrong way, or where there are many misunderstandings that lead to serious problems. If you want to find all of our SQLskills SQL101 blog posts, check out SQLskills.com/help/SQL101.

This is an interesting misconception that I was asked about last week: (paraphrasing) Surely a SELECT operation can’t cause a database to change, because it’s just reading data, not altering it in any way, right?

Well, no. There are actually quite a few side effects of queries that only read data and never perform data changes (not counting a SELECT … INTO, of course). Here are four that spring to mind…

Statistics Creation

If the database property Auto Create Statistics is set to True, when a query is being compiled and the query optimizer determines that a statistic could be created that would aid the optimization process, it will create that statistic before optimization continues, thus changing the database. Your SELECT statement could cause this to happen.

Statistics Update

If the database property Auto Update Statistics is set to True, when a query is being compiled and a necessary statistic is determined to be out-of-date, it will be automatically updated before optimization continues, thus changing the database. Your SELECT statement could cause this to happen. Additionally, if the Auto Update Statistics Asynchronously property is enabled, the statistic will be automatically updated, but after the optimization process (so the compiling query doesn’t have to wait).

Ghost Cleanup

Ghost cleanup is the funky process for removing deleted records. For all indexes, and for heaps when some form of snapshot isolation is involved, deleting a record just marks it as deleted. After the deleting transaction commits, the deleted record is later removed by a background process called the ghost cleanup task. The interesting thing though is that a deleted record is not immediately entered in the task’s list of things to do. It’s usually not until the *next* use of the data file page that the Storage Engine sees that there’s a deleted record and enters it in the task’s to-do list. So, your SELECT statement could be that ‘next’ use of a data file page with a recently deleted record on that causes the record to be cleaned up by the ghost cleanup task.

Query Store

From SQL Server 2016 onward, if you have the Query Store enabled, by default every query execution will cause some metrics to be captured and stored in the Query Store’s system tables (which you can query with various DMVs). You can stop it capturing information for all queries by setting the QUERY_CAPTURE_MODE to AUTO, which causes it to not capture “insignificant” queries, but you can’t specify what “insignificant” means. Anyway, your SELECT statement could cause this to happen.

Summary

So as you can see, just because you’re not deliberately making a change in a database, that doesn’t mean that you won’t trigger something else in SQL Server to make a change. And then there’s the Auto Shrink option for a database, which of course should *never* be enabled! (see here for explanation…)

13 thoughts on “SQLskills SQL101: How can a SELECT cause a database to change?

  1. Or the excellent one I ran across where someone was running a trace of all select statements, and logging that to a table inside the database. (sigh)

    1. I’ll bite. I need this information: Who is accessing which tables. Previously the DBA turned on extended events which created 4x1GB files every day that were a pain to process. But we got the information. What is a better way? Thanks.

      1. SQL Server Audit – been in the product since SQL Server 2008. It also generates data files. Or a more heavy-handed way would be to use a trigger.

        1. Isn’t the Profiler overhead related to its gui? How about a server-side trace stored to a file (and importing that to DB when needed)?

    1. Of course, but in my post I said “There are actually quite a few side effects of queries that only read data and never perform data changes.” – that doesn’t cover a SELECT … INTO.

  2. Sir , Is it also possible that our select fetching records of size of 10% of buffer pool and causing dirty pages to be flushed by lazy writer and so causing making changes to database.

    1. No – a dirty page in memory has already been changed. If it stays in memory or is written to disk (thus becoming a clean page in memory) makes no difference – it’s the same page that will be read by a query. There are no extra changes to a database because a dirty page is written to disk.

Leave a Reply

Your email address will not be published. Required fields are marked *

Other articles

Imagine feeling confident enough to handle whatever your database throws at you.

With training and consulting from SQLskills, you’ll be able to solve big problems, elevate your team’s capacity, and take control of your data career.