June 25, 2012 at 10:06 am
I have index statistics taken care of by a scripted maintenance plan but I'm going to be setting up a separate plan to take care of updating the column statistics. Is there a query for determining when the columns were last updated? I've determined what columns are not in any indexes to cover "yes, I need to update column stats" but they don't appear in sys.stats so it looks like that table just contains info for the index stats.
June 25, 2012 at 11:13 am
I don't think when a statsitic has been updated/created is exposed;
however, you can use a formulat to determine if any existing statistics ned to be updated ro not;
I slapped this example together a long time ago (it's using sysindexes instead of sys.indexes Sorry Gail!)
the idea behind it is any table with 1000 rows having been modified is worth of a statistics update, and depedning on hte size fo the table, more often than the default of 20% of the rows; big tables often need statsitics updated more often than that.
see if this helps?
--The Analysis: my crappy assumptions:
--UPDATE STATISTICS dbo.GMPVDET
--tables under 1000 rows, I'll leave then at 20%
--tables with more rows than that, I'll use an arbitrary sliding scale formula.
--formula to be modified based on analysis
SELECT X.*,
ISNULL(CASE
WHEN X.[Total Rows]<=1000
THEN
CASE
WHEN [Percent Modified] >=20.0
THEN 'UPDATE STATISTICS ' + [Schema Name] + '.' + [Table Name] + ' WITH ALL, FULLSCAN --20% Small Table Rule'
END
WHEN [Percent Modified] = 100.00
THEN 'UPDATE STATISTICS ' + [Schema Name] + '.' + [Table Name] + ' WITH ALL, FULLSCAN --100% No real Stats Rule'
--WHEN X.[Rows Modified] > 1000
--THEN 'UPDATE STATISTICS ' + [Schema Name] + '.' + [Table Name] + ' WITH ALL, FULLSCAN --1000 Rows Modified Rule'
ELSE
CASE
WHEN X.[Total Rows] > 1000000000 --billion rows
THEN CASE
WHEN [Percent Modified] > 0.1
THEN 'UPDATE STATISTICS ' + [Schema Name] + '.' + [Table Name] + ' WITH ALL, FULLSCAN -- 1B Big Table Rule'
END
WHEN X.[Total Rows] > 100000000 --hundred million rows
THEN CASE
WHEN [Percent Modified] > 1.0
THEN 'UPDATE STATISTICS ' + [Schema Name] + '.' + [Table Name] + ' WITH ALL, FULLSCAN -- 100M Big Table Rule'
END
WHEN X.[Total Rows] > 10000000 --ten million rows
THEN CASE
WHEN [Percent Modified] > 2.0
THEN 'UPDATE STATISTICS ' + [Schema Name] + '.' + [Table Name] + ' WITH ALL, FULLSCAN -- 10M Big Table Rule'
END
WHEN X.[Total Rows] > 1000000 --million rows
THEN CASE
WHEN [Percent Modified] > 5.0
THEN 'UPDATE STATISTICS ' + [Schema Name] + '.' + [Table Name] + ' WITH ALL, FULLSCAN -- 1M Big Table Rule'
END
WHEN X.[Total Rows] > 100000 --hundred thousand rows
THEN CASE
WHEN [Percent Modified] > 10.0
THEN 'UPDATE STATISTICS ' + [Schema Name] + '.' + [Table Name] + ' WITH ALL, FULLSCAN -- 100K Big Table Rule'
END
WHEN X.[Total Rows] > 10000 --ten thousand rows
THEN CASE
WHEN [Percent Modified] > 20.0
THEN 'UPDATE STATISTICS ' + [Schema Name] + '.' + [Table Name] + ' WITH ALL, FULLSCAN -- 10K Big Table Rule'
END
END
END,'') AS [Statistics SQL]
FROM (
SELECT DISTINCT
DB_NAME() AS [Database],
S.name AS [Schema Name],
T.name AS [Table Name],
I.rowmodctr AS [Rows Modified],
P.rows AS [Total Rows],
CASE
WHEN I.rowmodctr > P.rows
THEN 100
ELSE CONVERT(decimal(8,2),((I.rowmodctr * 1.0) / P.rows * 1.) * 100.0)
END AS [Percent Modified]
FROM
sys.partitions P
INNER JOIN sys.tables T ON P.object_Id = T.object_id
INNER JOIN sys.schemas S ON T.schema_id = S.schema_id
INNER JOIN sysindexes I ON P.object_id = I.id
WHERE P.index_id in (0,1)
AND I.rowmodctr > 0
) X
WHERE [Rows Modified] > 1000
ORDER BY [Rows Modified] DESC
Lowell
June 25, 2012 at 3:41 pm
Mindy Hreczuck (6/25/2012)
I have index statistics taken care of by a scripted maintenance plan but I'm going to be setting up a separate plan to take care of updating the column statistics. Is there a query for determining when the columns were last updated? I've determined what columns are not in any indexes to cover "yes, I need to update column stats" but they don't appear in sys.stats so it looks like that table just contains info for the index stats.
Using SSMS 2012 against a SQL 2008R2 instance if I right-click on a stat in SSMS and go to Properties...
I see the last update date:
Tracing what SSMS 2012 did I was able to poach this query to get a column stat update date:
DECLARE @statistic_name SYSNAME = N'_WA_Sys_00000002_7D78A4E7',
@table_name SYSNAME= N'activity_snapshot',
@schema_name SYSNAME = N'dbo';
SELECT STATS_DATE(st.object_id, st.stats_id) AS [LastUpdated]
FROM sys.tables AS tbl
INNER JOIN sys.stats st ON st.object_id = tbl.object_id
WHERE (st.name = @statistic_name)
AND (
(tbl.name = @table_name
AND SCHEMA_NAME(tbl.schema_id) = @schema_name )
);
I ran a query with a non-indexed column in the WHERE-clause to force SQL Server to create a new column stat and I was able to see the update date using the above query. As for how to differentiate the stat update date from the stat create date, I am not sure if we can do that.
I also ran this to update the column stat:
UPDATE STATISTICS dbo.activity_snapshot _WA_Sys_00000002_7D78A4E7;
and the query (and UI) showed a new update date.
There are no special teachers of virtue, because virtue is taught by the whole community.
--Plato
June 25, 2012 at 3:46 pm
I thought I was in a SQL 2008 Forum when I posted, so I tested on SQL 2008. I noticed I was in a SQL 2005 Forum after I posted. I just tested the query against a SQL 2005 database and it behaved the same.
There are no special teachers of virtue, because virtue is taught by the whole community.
--Plato
June 25, 2012 at 4:28 pm
Just one point... Column statistics do indeed appear in sys.stats, all statistics are in that view both column and index. Index stats get updated when the index is rebuilt, column stats only get updated when update stats is run or an auto update kicks in.
Gail Shaw
Microsoft Certified Master: SQL Server, MVP, M.Sc (Comp Sci)
SQL In The Wild: Discussions on DB performance with occasional diversions into recoverability
June 29, 2012 at 9:06 am
Thanks guys, yes I see the numbers in the properties of my SQL 2005 so that's good info.
And Gail, reading this I came to realize that as well. The query I had was tweaked so among the table joins it was only returning the stats for the indexes.
So here's my next question, is it a safe assumption that if I use the built-in update statistics task that it will do all columns, not just outdated ones? I updated the stats for columns on a copy of a db last night via that task and it ran 14 hrs... and most of the time was just on one (the largest) table. So if I want to break it down so it will finish within maintenance windows, I'm assuming I'll need to script it out. Yes?
June 29, 2012 at 9:09 am
If you use the maintenance plan task, it will update everything.
Gail Shaw
Microsoft Certified Master: SQL Server, MVP, M.Sc (Comp Sci)
SQL In The Wild: Discussions on DB performance with occasional diversions into recoverability
June 29, 2012 at 9:29 am
Ok. A-scripting I shall go!
June 29, 2012 at 10:31 am
You may have something very granular or customizable planned in terms of your scripting effort so this may not be applicable, or these options may not satisfy your requirements, but I figured I would throw them out there since they were not mentioned and they may save you some time:
1. sp_updatestats (SQL Server 2005).
In SQL Server 2005, sp_updatestats updates only those statistics that require updating based on the rowmodctr information in the sys.sysindexes compatibility view; therefore, preventing unnecessary updates of unchanged items.
2. SQL Server Index and Statistics Maintenance by Ola Hallengren
Setting the UpdateStatistics parameter to COLUMNS, the OnlyModifiedStatistics parameter to YES and the StatisticsSample to FULLSCAN or SAMPLE you can have it only update stats that have changed since the last stats update, and with a sample size of your choice.
There are no special teachers of virtue, because virtue is taught by the whole community.
--Plato
June 29, 2012 at 11:25 am
opc.three (6/29/2012)
You may have something very granular or customizable planned in terms of your scripting effort so this may not be applicable, or these options may not satisfy your requirements, but I figured I would throw them out there since they were not mentioned and they may save you some time:1. sp_updatestats (SQL Server 2005).
In SQL Server 2005, sp_updatestats updates only those statistics that require updating based on the rowmodctr information in the sys.sysindexes compatibility view; therefore, preventing unnecessary updates of unchanged items.
Well, BoL's not entirely accurate there. The 'threshold' that sp_updatestats uses is 1 row.
Gail Shaw
Microsoft Certified Master: SQL Server, MVP, M.Sc (Comp Sci)
SQL In The Wild: Discussions on DB performance with occasional diversions into recoverability
June 29, 2012 at 12:32 pm
GilaMonster (6/29/2012)
opc.three (6/29/2012)
You may have something very granular or customizable planned in terms of your scripting effort so this may not be applicable, or these options may not satisfy your requirements, but I figured I would throw them out there since they were not mentioned and they may save you some time:1. sp_updatestats (SQL Server 2005).
In SQL Server 2005, sp_updatestats updates only those statistics that require updating based on the rowmodctr information in the sys.sysindexes compatibility view; therefore, preventing unnecessary updates of unchanged items.
Well, BoL's not entirely accurate there. The 'threshold' that sp_updatestats uses is 1 row.
Parsing a bit, but unchanged seems to be an accurate characterization. Misleading may be a fair assessment of that slice of the doc though. Ola's code does the same, checking this when @OnlyModifiedStatistics = 'Y':
sysindexes.[rowmodctr] <> 0
That's why I hedged and said something very granular or customizable planned in terms of your scripting effort. If one wanted to check rowmodctr manually and compare that to the number of rows in the stat it could help get closer to smart stats updates. I thought rowmodctr might become skewed since the column tracks updates but the engine seems to be aware when the same index entry is updated, meaning rowmodctr could be of service. At any rate, I read that since SQL 2005 the real story (the one used by auto update stats algorithms) is not available in any catalog view, only system tables that require we use DAC to see.
There are no special teachers of virtue, because virtue is taught by the whole community.
--Plato
July 1, 2012 at 2:33 am
Mindy Hreczuck (6/25/2012)
I have index statistics taken care of by a scripted maintenance plan but I'm going to be setting up a separate plan to take care of updating the column statistics. Is there a query for determining when the columns were last updated? I've determined what columns are not in any indexes to cover "yes, I need to update column stats" but they don't appear in sys.stats so it looks like that table just contains info for the index stats.
The function STATS_DATE() exposes the date\time of the last stats updates.
-----------------------------------------------------------------------------------------------------------
"Ya can't make an omelette without breaking just a few eggs" 😉
Viewing 12 posts - 1 through 11 (of 11 total)
You must be logged in to reply to this topic. Login to reply