SQL SERVER 2005 uses ALTER INDEX syntax to reindex database. SQL SERVER 2005 supports DBREINDEX but it will be deprecated in future versions.
When any data modification operations (INSERT, UPDATE, or DELETE statements) table fragmentation can occur. DBCC DBREINDEX statement can be used to rebuild all the indexes on all the tables in database. DBCC DBREINDEX is efficient over dropping and recreating indexes.
Execution of Stored Procedure sp_updatestats at the end of the Indexes process ensures updating stats of the database.When any data modification operations (INSERT, UPDATE, or DELETE statements) table fragmentation can occur. DBCC DBREINDEX statement can be used to rebuild all the indexes on all the tables in database. DBCC DBREINDEX is efficient over dropping and recreating indexes.
Method 1: My Preference
USE
MyDatabase
GO
EXEC
sp_MSforeachtable
@command1
=
"print '?' DBCC DBREINDEX ('?', ' ', 80)"
GO
EXEC
sp_updatestats
GO
Method 2:
USE
MyDatabase
GO
CREATE PROCEDURE
spUtil_ReIndexDatabase_UpdateStats
AS
DECLARE
@MyTable
VARCHAR
(
255
)
DECLARE
myCursor
CURSOR FOR
SELECT
table_name
FROM
information_schema.tables
WHERE
table_type
=
'base table'
OPEN
myCursor
FETCH
NEXT
FROM
myCursor
INTO
@MyTable
WHILE
@@FETCH_STATUS
=
0
BEGIN
PRINT
'Reindexing Table: '
+
@MyTable
DBCC
DBREINDEX
(
@MyTable
,
''
,
80
)
FETCH
NEXT
FROM
myCursor
INTO
@MyTable
END
CLOSE
myCursor
DEALLOCATE
myCursor
EXEC
sp_updatestats
GO
When exploring a SQL Server database for the first time, it’s always useful to identify the most populated tables first because they are very likely to be the most important tables. To do this in a situation where there are tight time-scales, it’s possible to use some undocumented SQL Server procedures to quickly produce a list of the tables which have the most rows.
Before proceeding, however, it’s wise to note that undocumented stored procedures are not guaranteed by Microsoft. Further, they are not ‘fixed’ so they could change without warning, so use this command at your own discretion, and treat the results with care!
One example of an undocumented SQL Server procedure which has been useful is SP_FOREACHTABLE. Although it’s not guaranteed, it might be useful for some to try it out as a starting point when exploring data, when it’s useful to find out the most populated tables in your new unexplored database.
In this example, a new table called TableRowCount will be created. This table will hold the results of the execution of SP_FOREACHTABLE. To assist you, the SQL to do this is given below:
/****** Check if table TableRowCount exists already, and if so, delete it ******/ IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[TableRowCount]') AND type in (N'U'))
DROP TABLE [dbo].[TableRowCount]
GO
/****** Create table TableRowCount ******/
CREATE TABLE [TableRowCount](
TableName sysname,
[TableRowCount] int )
Once the table is created, the SP_FOREACHTABLE procedure is executed as follows:
/****** Execute stored procedure, and save results in table TableRowCount ******/
EXEC sp_MSForEachTable 'INSERT [TableRowCount](TableName, [TableRowCount]) SELECT ''?'', COUNT(*) FROM ?'
Then, it’s possible to retrieve the results of this command from the TableRowCount table, as follows:
/****** Display the results from table TableRowCount, in descending order ******/
select * from TableRowCount
order by TableRowCount.TableRowCount desc
The above statement will sort the data so that the table with the highest number of rows will appear at the top. It's a guess that the most populated table is an important one, but it's not a bad guess all the same!
DROP TABLE [dbo].[TableRowCount]
GO
/****** Create table TableRowCount ******/
CREATE TABLE [TableRowCount](
TableName sysname,
[TableRowCount] int )
Once the table is created, the SP_FOREACHTABLE procedure is executed as follows:
/****** Execute stored procedure, and save results in table TableRowCount ******/
EXEC sp_MSForEachTable 'INSERT [TableRowCount](TableName, [TableRowCount]) SELECT ''?'', COUNT(*) FROM ?'
Then, it’s possible to retrieve the results of this command from the TableRowCount table, as follows:
/****** Display the results from table TableRowCount, in descending order ******/
select * from TableRowCount
order by TableRowCount.TableRowCount desc
The above statement will sort the data so that the table with the highest number of rows will appear at the top. It's a guess that the most populated table is an important one, but it's not a bad guess all the same!
Empty All Tables from database:
CREATE PROCEDURE sp_EmplyAllTable
AS
EXEC sp_MSForEachTable ‘ALTER TABLE ? NOCHECK CONSTRAINT ALL’
EXEC sp_MSForEachTable ‘DELETE FROM ?’
EXEC sp_MSForEachTable ‘ALTER TABLE ? CHECK CONSTRAINT ALL’
GO
|
DBA: "I deleted all of the data from my database and now it contains table structure only. However, when I tried to insert new data in my tables I noticed that my identity values starts from the same number where they actually were before I deleted the data."
Pinal: "How did you delete the data?"
DBA: "Running Delete in Loop?"
Pinal: "What was the need of such need?"
DBA: "It was my development server and I needed to repopulate the database."
Pinal: "Oh so why did not you use TRUNCATE which would have reset the identity of your table to the original value when the data got deleted? This will work only if you want your database to reset to the original value. If you want to set any other value this may not work."
DBA: (silence for 2 days)
DBA: "I did not realize it. Meanwhile I regenerated every table's schema anddropped the table and re-created it."
Pinal: "Oh no, that would be extremely long and incorrect way. Very bad solution."
DBA: "I understand, should I just take backup of the database before I insert the data and when I need, I can use the original backup to restore the database. This way I will have identity beginning with 1."
Pinal: "This going totally downhill. It is wrong to do so on multiple levels. Did you even read my earlier email about TRUNCATE."
DBA: "Yeah. I found it in spam folder."
Pinal: (I decided to stay silent)
DBA: (After 2 days) "Can you provide me script to reseed identity for all of my tables to value 1 without asking further question."
Pinal:
USE DATABASE
;
EXEC
sp_MSForEachTable
'
IF OBJECTPROPERTY
(object_id
(''?''), ''TableHasIdentity'') = 1
DBCC CHECKIDENT (''?'', RESEED, 1)'
GO
Our conversation ended here. If you have directly jumped to this statement, I encourage you to read the conversation one time. There is difference between reseeding identity value to 1 and reseeding it to original value - I will write an another blog post on this subject in future.
Deleting all records from all tables
sp_MsForEachTable 'TRUNCATE TABLE ?'
or
EXEC sp_msforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'
EXEC sp_msforeachtable 'DELETE FROM ?'
EXEC sp_msforeachtable 'ALTER TABLE ? WITH CHECK CHECK CONSTRAINT ALL'
EXEC sp_msforeachtable 'DELETE FROM ?'
EXEC sp_msforeachtable 'ALTER TABLE ? WITH CHECK CHECK CONSTRAINT ALL'
Deleting all records in case of FK And PK and for excluding some tables
- EXEC sp_msforeachtable ‘ALTER TABLE ? NOCHECK CONSTRAINT ALL’
exec sp_MSforeachtable
@command1 = ‘delete from ?’,
@whereand = ‘and o.name not in( ”ABC”,”XYZ”)’
@command1 = ‘delete from ?’,
@whereand = ‘and o.name not in( ”ABC”,”XYZ”)’
EXEC sp_msforeachtable ‘ALTER TABLE ? WITH CHECK CHECK CONSTRAINT ALL’
EXEC sp_msforeachtable @command1="print '?'"
Example to print all table names excluding some tables
exec sp_MSforeachtable
@command1 = "print '?'",
@whereand = " and o.name not in( 'Average7')"
Or
exec sp_MSforeachtable
@command1 = 'print "?"',
@whereand = 'and o.name not in( "Average7")'
exec sp_MSforeachtable
@command1 = ‘delete from ?',
@whereand = ‘ and o.name not in(“Average7”)’
Note - @whereand should not be greater then 128 in length
thanks, great info, here's another piece of code that i like to use in order to find a list of the most populated tables within my database : http://www.sqlpentruincepatori.ro/most-populated-tables-from-the-database-sql-server/
ReplyDelete