Saturday, April 18, 2015

Rebuild Indexes of database with fragmentation more than 30%

Rebuild of indexes is the prime job of a DBA as heavily fragmented indexes can degrade query performance and cause your application to respond slowly. We should reorganize indexed with fragmentation between > 5% and < 30% and rebuild indexes if fragmentation more than 30%. To rebuild indexes we have a Rebuild indexes task in maintenance Plan.
          
                                                                                   




If we see the T-SQL of this task, it will rebuild all indexes. As rebuilding all indexes would be nightmare for the server because as it take much resources. This is drawback of Rebuild Index Task.
To overcome this we write a custom script that only select indexes to rebuild that have Fragmentation more than 30%.
Sys.dm_db_index_physical_stats database management function return handy information about index fragmentation. We will use this function in script below. This script use table variable and does not require any cursor or temp table.
declare @frag_Temp as Table
(
    ID int identity(1,1),
       [objectid] [int] NULL,
       [indexid] [int] NULL,
       [partitionnum] [int] NULL,
       [frag] [float] NULL
)

Declare @Count int
Declare @i tinyint=1
DECLARE @schemaname sysname;
DECLARE @objectname sysname;
DECLARE @indexname sysname;
DECLARE @objectid int;
DECLARE @indexid int;
DECLARE @partitionnum bigint;
DECLARE @partitioncount bigint;
DECLARE @SQLCommand as Nvarchar(3000)
insert into @frag_Temp
SELECT
    object_id AS objectid,
    index_id AS indexid,
    partition_number AS partitionnum,
    avg_fragmentation_in_percent AS frag
FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL , NULL, 'LIMITED')
--Arguments 1(Database_ID,object_Id,Index_ID,partition,mode
WHERE avg_fragmentation_in_percent >= 30.0 AND index_id > 0;

select @Count=Count(*) from @frag_Temp --Get Total Count
       While(@i<=@Count)
          Begin
             select @objectid=objectid,@indexid=indexid,@partitionnum=partitionnum
                from @frag_Temp where ID=@i

              --Get tableName and its schema
                 select @objectname=o.name,@schemaname=c.name from
                 sys.objects o
                 inner join  sys.schemas c on o.schema_ID=c.schema_ID
                 where o.object_id=@objectid
               --Get Index Name
                     select @indexname=name
                     from sys.indexes
                     where index_id=@indexid and object_id=@objectid
               --Get Partition Count
               select @partitioncount=count(*) from sys.partitions
                     where object_id=@objectid and index_id=@indexid
      
                SELECT @SQLCommand= 'Alter Index ' + @indexname + ' ON ' +                                          @schemaname + '.' + @objectname + ' REBUILD'  
                      IF(@partitioncount>1)
                      SELECT @SQLCommand=@SQLCommand +  ' PARTITION='                                              convert(Char,@partitionnum);
                     
                   EXEC(@SQLCommand);

               --Increment Count
               set @i=@i+1

          End







Tuesday, February 25, 2014

Database diagram support objects cannot be installed because this database does not have a valid owner. To continue, first use the Files page of the Database Properties dialog box or the ALTER AUTHORIZATION statement to set the database owner to a valid login, then add the database diagram support objects.

When I right click on the database diagrams folder in SSMS to create new diagram. Following popup window open with error.


Solutions:
From the Message you can clearly see that the database does not have a valid user. We can have a valid user by running a query or through SSMS.
Query:
ALTER AUTHORIZATION ON DATABASE::TestDB TO sa
GO
Change Database name to your database in query.

SSMS:
Go to properties of a Database by right clicking the Database and then select File.
Change the owner by clicking the dotted button in highlighted part in the image below.


Thursday, February 20, 2014

Attach Database “Operating System Error 5 (Access is denied)” MSSQL Server 2012.

When I try to attach mdf file I got following error below.

Solution:
There are multiple solutions to this

1    1.    Move .mdf and .ldf to SQLServer install directory \Data\ folder (eg C:\Program Files (x86)\Microsoft SQL Server\MSSQL10.SQLEXPRESS\MSSQL\DATA) and then attach.
2    2. Give SQL SERVER SERVICE account full access to folder where mdf and ldf files are located.
3       3. Run as Administrator as in Below screens.
Run SSMS as admin as shown in screen below


Tuesday, February 18, 2014

Create Database Error "operating system error 112(There is not enough space on the disk.)"


I try to create database by generating script of another database, which was a huge Database. When I run the script below

USE [master]
GO

CREATE DATABASE [YourDB] ON  PRIMARY
( NAME = N'YourDB_1', FILENAME = N'G:\Data\YourDB.mdf' , SIZE = 230683968KB , MAXSIZE = UNLIMITED, FILEGROWTH = 10%),
 FILEGROUP [DWINDEX]
( NAME = N'YourDB_1_index', FILENAME = N'G:\Data\YourDB_1.ndf' , SIZE = 86941440KB , MAXSIZE = UNLIMITED, FILEGROWTH = 10%)
LOG ON
( NAME = N'YourDB_1_log', FILENAME = N'F:\Logs\SQL\YourDB_2.ldf' , SIZE = 2568128KB , MAXSIZE = 2048GB , FILEGROWTH = 10%),
( NAME = N'YourDB_2_log', FILENAME = N'F:\Logs\SQL\YourDB_3.ldf' , SIZE = 32256KB , MAXSIZE = 2048GB , FILEGROWTH = 1024KB ),
( NAME = N'YourDB_3_log', FILENAME = N'F:\Logs\SQL\YourDB_4.ldf' , SIZE = 19520KB , MAXSIZE = 2048GB , FILEGROWTH = 1024KB ),
( NAME = N'YourDB_31_log', FILENAME = N'F:\Logs\SQL\YourDB_5.ldf' , SIZE = 79488KB , MAXSIZE = 2048GB , FILEGROWTH = 10%)
GO

It  runs for almost half hour and return following error.

Error
Msg 5149, Level 16, State 3, Line 3
MODIFY FILE encountered operating system error 112(There is not enough space on the disk.) while attempting to expand the physical
file 'G:\Data\YourDB_1.ndf'.
Msg 1802, Level 16, State 4, Line 3
CREATE DATABASE failed. Some file names listed could not be created. Check related errors.

Solution:

When we create script of big Database, it goes to claim space at hard disk given in Size property of File and query took lot of time. Solution of the above query is quite simple, always set size property of mdf file to 4000KB and LDF file property to 1024KB to create new Database.