{"id":8898,"date":"2016-04-27T02:47:08","date_gmt":"2016-04-27T02:47:08","guid":{"rendered":"https:\/\/test.simple-talk.com\/uncategorized\/are-the-statistics-being-updated\/"},"modified":"2016-07-28T10:58:05","modified_gmt":"2016-07-28T10:58:05","slug":"are-the-statistics-being-updated","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/other\/are-the-statistics-being-updated\/","title":{"rendered":"Are the statistics being updated?"},"content":{"rendered":"<p>The auto-update statistics configuration updates statistics when the amount of row changes in the table achieves 20% of total rows.<\/p>\n<p>However, for tables with too many rows, this threshold is too high. For example, a table with 1 million rows will only update statistics after 200 thousands changes. That&#8217;s too much and can affect query plans and query performance.<\/p>\n<p>We can enable trace flag 2371 to change this behavior. Using this trace flag, threshold to trigger the auto-update statistics become dynamic. After 25k rows in the table, the amount of updates starts to decrease. A table with 1M rows needs around 3.2% of updates to trigger the auto-update statistics.<\/p>\n<p>Even with this trace flag enabled, an important administrative task is identifying if the auto-update statistics is running often enough and, if not, schedule the update statistics using a SQL Agent job.<\/p>\n<p>We can find when the last update statistics happened and how many row modifications happened since the last update statistics using sys.dm_db_stats_properties DMV with a few more joins.<\/p>\n<pre class=\"csharpcode\">SELECT\nSCHEMA_NAME([o].[schema_id]) AS [schema], [o].[name] as [TABLE],\n[s].[name] AS Statistic,\n[sp].[last_updated],\n[sp].[rows],\n[sp].[rows_sampled],\n[sp].[modification_counter] AS [Modifications]\nFROM \n    [sys].[stats] AS [s] inner join sys.stats_columns sc\n        on s.stats_id=sc.stats_id and s.object_id=sc.object_id\n    inner join sys.columns c\n        on c.object_id=sc.object_id and c.column_id=sc.column_id\n    inner join sys.objects o\n        on s.object_id=o.object_id\n    inner join sys.schemas sch\n        on o.schema_id=sch.schema_id\n    OUTER APPLY sys.dm_db_stats_properties ([s].[object_id],[s].[stats_id]) AS [sp]\nwhere sch.name&lt;&gt;'sys'\nand (sp.modification_counter &gt; 1000 or (sp.modification_counter * 100) &gt; sp.rows)   -- removes rows with too few modifications\norder by [Percent] desc,last_updated desc -- the result in order of priority<\/pre>\n<\/p>\n<p>Let&#8217;s create a user defined function to make all the work easier. The function StatisticsModifications will retrieve information about all statistics in the database:<\/p>\n<pre class=\"csharpcode\">CREATE FUNCTION StatisticsModifications ()\nRETURNS TABLE \nAS\nRETURN \n(\nSELECT\nSCHEMA_NAME([o].[schema_id]) AS [schema], [o].[name] as [TABLE],\n[s].[name] AS Statistic,\n[sp].[last_updated],\n[sp].[rows],\n[sp].[rows_sampled],\n[sp].[modification_counter] AS [Modifications]\nFROM \n    [sys].[stats] AS [s] inner join sys.stats_columns sc\n        on s.stats_id=sc.stats_id and s.object_id=sc.object_id\n    inner join sys.columns c\n        on c.object_id=sc.object_id and c.column_id=sc.column_id\n    inner join sys.objects o\n        on s.object_id=o.object_id\n    inner join sys.schemas sch\n        on o.schema_id=sch.schema_id\n    OUTER APPLY sys.dm_db_stats_properties ([s].[object_id],[s].[stats_id]) AS [sp]\nwhere sch.name&lt;&gt;'sys'\n\n)<\/pre>\n<p>Now we can use this function with some filters to retrieve the most out dated statistics.<\/p>\n<pre class=\"csharpcode\">select     [schema], [Table],\n     [Statistic],\n    [last_updated], [rows],\n    [rows_sampled], [Modifications],    \n(100 * modifications)\/[rows] [Percent] \nfrom dbo.statisticsmodifications()\n\/* removes rows with too few modifications *\/\nwhere (modifications &gt; 1000 or (modifications * 10) &gt; [rows])   \norder by [Percent] desc,last_updated desc<\/pre>\n<p>Using the result of the above query you can identify if the update statistics are running in regular intervals or if you need to schedule the update statistics.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The auto-update statistics configuration updates statistics when the amount of row changes in the table achieves 20% of total rows. However, for tables with too many rows, this threshold is too high. For example, a table with 1 million rows will only update statistics after 200 thousands changes. That&#8217;s too much and can affect query&#8230;&hellip;<\/p>\n","protected":false},"author":50808,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[2],"tags":[],"coauthors":[],"class_list":["post-8898","post","type-post","status-publish","format-standard","hentry","category-other"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/8898","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/50808"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=8898"}],"version-history":[{"count":7,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/8898\/revisions"}],"predecessor-version":[{"id":42545,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/8898\/revisions\/42545"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=8898"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=8898"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=8898"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=8898"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}