March 1, 2005 at 1:46 pm
I have a script that will drop all statistics and indexes. Our database has proprietary indexes that I will not be able to replace. However, I need to drop all stand alone statistics. Is there a way to filter out the ones I need?
March 2, 2005 at 7:17 am
how can an index be proprietary? any index created on a table will show up using sp_helpindex <tablename>, right? any index created can be scripted out, and the same goes for statistics.
on any table you can run sp_helpstats <tablename> and get the list of all statistics which referenced that table id. the statistics which start with _WA_Sys_ are the ones SQL Server created automatically as part of it's execution plans. statistics that do not start with _WA_Sys_ are probably the statistics you are referencing.
anyway, this script "Drop table indexes, constraints and statistics":
http://www.sqlservercentral.com/scripts/contributions/213.asp
could probalby be adapted to what you want, or simply use the search to search scripts for indexes or statistics and see what other users have contributed.
Lowell
March 2, 2005 at 9:44 am
What I mean is that they have manually built indexes that make our database faster, so I can't drop them. However, they said they have no stand alone statistics, of which I need to drop. I was hoping for a field that said "Statistic" or "Index". That way I could drop and rebuild stats with a script that runs regularly and just update the indexes.
What started all this was 2 stats that noone knows who built that got in the way on our updates. I am thinking they may also be causing some other problems we are experiencing. Either way a clean house is an efficient house.
March 2, 2005 at 10:32 am
The script below uses a cursor nested within a cursor to get the job done.
in this case it drops ALL statistics, leaving indexes alone.
SET NOCOUNT ON
--ONE OF THOUSE HORRIBLE CURSOR WITHIN A CURSOR THINGS:
DECLARE @TABLENAME VARCHAR (30),
@STATNAME VARCHAR(1024),
@SQLSTRING VARCHAR(2000),
@OUTERFETCH INT
BEGIN
DECLARE TCURSOR CURSOR FOR
SELECT NAME FROM SYSOBJECTS WHERE XTYPE='U'; --ALL USER TABLES
CREATE TABLE #TEMPSTATS(STATISTICS_NAME VARCHAR(1024),STATISTICS_KEYS VARCHAR(1024))
OPEN TCURSOR
FETCH NEXT FROM TCURSOR INTO @TABLENAME
SET @OUTERFETCH=@@FETCH_STATUS
WHILE @OUTERFETCH = 0
BEGIN
PRINT 'CHECKING TABLE :' + @TABLENAME
TRUNCATE TABLE #TEMPSTATS
INSERT INTO #TEMPSTATS
EXEC SP_HELPSTATS @OBJNAME=@TABLENAME
DECLARE STATISTICSCURSOR CURSOR FOR SELECT DISTINCT STATISTICS_NAME FROM #TEMPSTATS
OPEN STATISTICSCURSOR
FETCH NEXT FROM STATISTICSCURSOR INTO @STATNAME
WHILE @@FETCH_STATUS = 0
BEGIN
--ALL STATISTICS; DO YOU WANT TO DIFFERENTIATE AGAINST _WA_Sys_ STATISTICS?
SET @SQLSTRING = 'DROP STATISTICS ' + @TABLENAME + '.' + @STATNAME + ''
PRINT @SQLSTRING
EXEC (@SQLSTRING)
FETCH NEXT FROM STATISTICSCURSOR INTO @STATNAME
END
CLOSE STATISTICSCURSOR
DEALLOCATE STATISTICSCURSOR
FETCH NEXT FROM TCURSOR INTO @TABLENAME
SET @OUTERFETCH=@@FETCH_STATUS
END
CLOSE TCURSOR
DEALLOCATE TCURSOR
DROP TABLE #TEMPSTATS
END
i wrapped this into an sproc, stuck it in master, and it works for all databases as well... simply add
create procedure sp__dropstatistics as
to the top of the code
Lowell
March 2, 2005 at 11:11 am
Thank you Lowell.
Now I just have to load it on my test machine, reverse engineer it to figure out how you did it.
March 2, 2005 at 11:22 am
How's this for reverse engineering :
Select Object_name(id) as TableName, 'DROP STATISTICS [' + Object_name(id) +'].[' + name + ']' from dbo.SysIndexes where indid > 0 and indid 0 ORDER BY Object_name(id)
--64 | 8388608 is for user and system stats
paste the 2nd column in QA and execute (drops ALL STATISQUES)
March 2, 2005 at 11:47 am
Remi's knowing the nuances of allowable indid and status values lets him use that to find the drop statements; you'd still have to wrap that into a cursor to get it to actually drop the statistics for you.
Remi did you have a source for knowing that AND-ing the status value returned a statistinc and not an index? if you had a source could you share? little nuances like that make better coding,
thanks
Lowell
March 2, 2005 at 12:03 pm
This is still personal preference :
1 - Cursor = £@£½¤¢¤[¼¢8(*?%(*?/$ £¢¤£¢¤
however I agree that they have their utility once in a while... especially hwen doing admin stuff like this.
2 - Automated procs like these make me shiver because I'm not the only person who has dbo access on the server and I've seen those other guy run procs without knowing what they really do and I frankly don't expect them to understand what an advanced stored proc like that does on the first read. Also I've been known to run the wrong proc on more than 1 occasion, so I prefer to run these types of procs manually so that I can control what affects performance on the server (either from running the proc or the side effects of the proc).
3 - this line of code is all I needed to get me started :
EXEC SP_HELPSTATS
Open EM, expand master, stored procs and find SP_HELPSTATS and read the code. It's well commented and easy to understand. From that and what I already knew from SysIndexes it was pretty easy to build the command list query (I have worked a lot on systables a few months back... I remembered that stats are indexes that have a status that skyrockets well into the millions and that their name always starts with "_WA_Sys_". However I have never created user stats which seem that have a much lower status number).
March 2, 2005 at 12:05 pm
Forgot to mention this :
indid >>
1 = Clustered index
>1 = non clustered
255 = used if the table as binary or text field(s)
0 = no clustered index
[EDITED]
0 = HEAP
March 2, 2005 at 12:23 pm
Lowell's script produced these errors
Cannot DROP the index 'hind_697105574_1A_5A_6A_56A_75A_8A_14A_24A_53A_68A_74A' because it is not a statistics collection.
DROP STATISTICS Serial.hind_697105574_56A
Server: Msg 3739, Level 11, State 1, Line 1
however Remi's didn't. I am releading the database to test again. It seems you are using the same drop statement just differnet select statements, correct? It's these "hind_" lines which are giving me the most trouble.
March 2, 2005 at 12:28 pm
This doesn't seem to be a system stat, maybe it's a user stat that the system is using... or some index type that I don't know.
Are you sure that my version dropped it? Or did it not select it in the list?
[Edited]
Now that I think of it it's maybe just a user stat that has been dropped by a developper while the proc was running or something like that... would make more sens.
March 2, 2005 at 1:35 pm
i found out that hind_ items are hypothetical indexes that are used by the index tuning wizard, they are supposed to be auto-removed when the tuning is done; see:
http://support.microsoft.com/kb/293177
The hypothetical indexes created by the Index Tuning Wizard start with a name of "hind_%" and should not exist after the tuning has finished; they should all be removed.
I think wrapping Remi's code in a cursor is a better idea, but the bandaid for what i wrote is to wrap the inner cursors workload in an if statement:
IF LEFT(@STATNAME,5) <> 'HIND_'
BEGIN
--ALL STATISTICS; DO YOU WANT TO DIFFERENTIATE AGAINST _WA_Sys_ STATISTICS?
SET @SQLSTRING = 'DROP STATISTICS ' + @TABLENAME + '.' + @STATNAME + ''
PRINT @SQLSTRING
EXEC (@SQLSTRING)
END
Lowell
March 2, 2005 at 2:00 pm
Actually it would be better to use my query because I query SysIndexes only once and would use only 1 cursor. While your current code queries SysIndexes for every table in you db... I don't know how often you indend to run this... but I expect that this version would take a lot more time (5/10/?? fold).
March 2, 2005 at 3:18 pm
I found the problem!!!!
Article Id number 293177.
The people who wrote our database program ran a lot of Index Tuning Wizards. These temporary stats never left and are creating update loops on my server. Guess how many...over 50! It's those stats with the hind_% name.
I want to thank you two. I have learned much today.
March 2, 2005 at 3:20 pm
I see you found it first
However, neither script dropped it.
Viewing 15 posts - 1 through 15 (of 15 total)
You must be logged in to reply to this topic. Login to reply