Monthly Archives: May 2011

How to Find if my indexes are fragmented?

As we keep on adding more and more records or keep deleting records from tables we can cause fragmentation and thus in turn affect query performance.

Fragmentation can be of two kinds: internal and external

Internal Fragmentation: It is caused whenever there is a lot of empty space in the index pages. This can be controlled by fill factor which estimates as to how much of the page has to be filled with data.

External Fragmentation: It is caused whenever a new page is created in an extent because of massive addition of records and when the current extent is full, a new extent will be allocatted and the page gets assigned to that extent. But this page is not in the same extent as previous extent and thus causes more extent swtiches with additional reads in non-sequential manner.

1. DBCC Command:

DBCC SHOWCONTIG – it gives fragmentation of a particular table or an index. It can be used in conjunction with TABLERESULTS to out the results to a table. It gives a very important information about avg. page density, scan density and logical scan fragmentation.
[cc lang=”sql”]
Use adventureworks
go
DBCC SHOWCONTIG (‘Person.contact’)
go
[/cc]
If avg_fragmentation_in_percent is more than 30% it is highly fragmented and so rebuild indexes. (alter index <index name> on <table name> rebuild)

if less than 30% means moderately fragmented and so reorganize indexes. (alter index <index name> on <table name> reorganize)

If avg_page_space_used_in_percent is < 75% it means internal fragmentation

2. DMV:
[cc lang=”sql”]
–sys.dm_db_index_physical_stats  – takes 3 params (databaseid, tableid, indexid)
SELECT *
FROM
sys.dm_db_index_physical_stats(db_id(), NULL, NULL, NULL, NULL) a
WHERE
index_id > 0

— avoid heapsORDER BY A.avg_fragmentation_in_percent DESC
–JOIN WITH sys.objects, sys.indexes, sys.partitions, index_id > 0 –TO GET actual INDEX name.
[/cc]

Another way to capture the results in SQL is
[cc lang=”sql”]
SELECT *
INTO #tbl_Fragmentation
FROM sys.dm_db_index_physical_stats (DatabaseID, TableId, IndexId, NULL, DETAILED);
[/cc]

Stored Procedure or Query Execution Times

Today we will see different ways to calculate the execution times of a SQL Query.

Typically it happens that we are tasked to performance tune certain queries to find out which queries or procedures are taking more time than expected. Here are 3 choices one could follow:

1. Using SQL Profiler: Look for the events SQL:BatchCompleted, RPC:completed and then capture the exectution times in Milliseconds.

2. Using Getdate():

[cc lang=”sql”]
Declare @start datetime, @end datetime, @timediffinMS int
select @start = getdate()
select *  from sys.syscomments
— OR
EXEC SP_WHO2
select @end = getdate()
select @timediffinMS = datediff (ms, @start, @end)
select @timediffinMS — this can be put in a table to analyze the time taken.

[/cc]

3. SET Command:

[cc lang=”sql”]
SET STATISTICS TIME ON
select * from sys.sysobjects
SET STATISTICS TIME OFF
[/cc]

Look for the last total CPU time and CPU elapsed times.

Note: Sometimes when you run these queries or procedures they remain in cache and hence run fast next time they are run, so please make sure to free up procedure cache using DBCC Dropcleanbuffers or DBCC Freeproccache or DBCC Freesystemcache (warning!! it has its own disadvantages of using above commands in production systems as they will remove all plans from plancache and all procedures will take more time or rarely less time to execute, so use with caution). The issue is that all procs get affected and not just the single proc you are trying to tune.

Also try to use CLIENT statistics option in SSMS that will average out based on a number of runs giving accurate picture avg. running time of the query.



In-Place Upgrade or Side-by-Side Migration

Predominantly we are in a situation where in certain servers need be upgraded. There will be a number of features we will be wanting to use with the latest versions of SQL Servers. Like the usage of CTEs, ranking functions in 2005 vis-a-vis 2000 or usage of datatime2, datetimeoffset datatypes in 2008 vis-a-vis 2005 or the usage of report builder 3.0, SSAS multiple cubes etc.,

Now one of the dilemma’s is whether to go for in-place upgrade or side-by-side migration. Here are the layman definitions:

In-Place Upgrade: Upgrading both the system and user databases at one go and which can include massive downtime for the databases depending on the size with similar or upgraded hardware as needed.

Side-by-Side migration: It involves creating a new instance on a new hardware and then transferring the databases once the server setup is complete. Further details:

Additional Points

In-place upgrade:

  • fastest and easiest
  • Need not change client connections
  • if the upgrade fails, it takes time to fix it and client apps will be unavailable during that time.
  • Should be easily handled even if technical know-how is limited in SQL admin area.
  • All the DBes are either offline or online at a time.
  • No new hardware needed but might need upgrade based on system requirements for the upgrade
  • Upgrading from non clustered instance to a clustered instance of 2008 is not possible.
  • Testing can be limited because it involves directly modifying the existing databases.
  • Linked server, replication and logshipping scenarios neednt be dealt with and relatively handling the issues rather than setting up all over again
  • Side-by-Side migration:

  • Users continue to access old server and databases
  • Server configurations and server objects like users, logins, SQL Server job agents need be synced with old server
  • clients are online most of the time and offline only for a brief moment when switching from old server name to new one.
  • Need more SQL Admin knowledge to configure collation settings, jobs, logins, roles etc.,
  • Have a choice to upgrade more Dbs and then do later one DB upgrade at a time on a timely basis.
  • Need new server to install a new instance of SQL Server.
  • Data transformation can be done using SSIS packages while moving the Databases.