Pages

Friday, May 16, 2025

Step-by-step: Shrink Transaction Log File

 To clear or shrink the log files in SQL Server and free up space, you can use DBCC SHRINKFILE along with a few preparatory steps, depending on your database recovery model.

⚠️ Important Notes Before Proceeding:

  • Shrinking log files should not be done frequently, as it can lead to fragmentation and performance issues.

  • Ensure this is done only when necessary (e.g., log file grew due to a large operation, and now it's not needed).

1. Check the database recovery model

SELECT name, recovery_model_desc 
FROM sys.databases 
WHERE name = 'YourDatabaseName';

If the recovery model is FULL or BULK_LOGGED, shrinking the log file requires backing up the transaction log first.

2. (Optional) Backup Transaction Log (Only if Recovery Model is FULL or BULK_LOGGED)

BACKUP LOG YourDatabaseName TO DISK = 'C:\Backup\YourDatabaseName_Log.trn';

3. Find the logical name of the log file

USE YourDatabaseName;
GO
EXEC sp_helpfile;

Note the logical name of the log file (usually ends with _log).

4. Shrink the log file

USE YourDatabaseName;
GO
DBCC SHRINKFILE (YourLogFileLogicalName, 1);  -- Shrink to 1 MB

You can change 1 to a more reasonable value (e.g., 1000 for 1 GB) depending on how much space you want to retain.

🔁 To Apply on All Databases:

You can generate the script dynamically for all databases using the following:


DECLARE @DBName NVARCHAR(128);

DECLARE @SQL NVARCHAR(MAX);


DECLARE db_cursor CURSOR FOR 

SELECT name FROM sys.databases 

WHERE state_desc = 'ONLINE' AND database_id > 4; -- Exclude system DBs


OPEN db_cursor;

FETCH NEXT FROM db_cursor INTO @DBName;


WHILE @@FETCH_STATUS = 0

BEGIN

    SET @SQL = '

    USE [' + @DBName + '];

    DECLARE @LogFile NVARCHAR(128);

    SELECT @LogFile = name FROM sys.database_files WHERE type_desc = ''LOG'';

    DBCC SHRINKFILE (@LogFile, 1);

    ';

    EXEC (@SQL);

    FETCH NEXT FROM db_cursor INTO @DBName;

END


CLOSE db_cursor;

DEALLOCATE db_cursor;

✅ Optional: Change Recovery Model to SIMPLE Temporarily

Only do this if point-in-time recovery is not needed:

ALTER DATABASE YourDatabaseName SET RECOVERY SIMPLE;

GO

DBCC SHRINKFILE (YourLogFileLogicalName, 1);

GO

ALTER DATABASE YourDatabaseName SET RECOVERY FULL;








Saturday, May 7, 2022

How to get next business day after excluding weekends in SQL

 Below query is helpful to find next business date by excluding weekends. We can use  same logic to find out the weekend.

1. Find next business day excluding weekend holiday.

   DECLARE @Current_date DATETIME = '14 Nov 2020'

   SELECT CASE

   WHEN (((DATEPART(DW,  @Current_date) - 1 ) + @@DATEFIRST ) % 7) IN (6)

           THEN @Current_date + 2

   WHEN (((DATEPART(DW,  @Current_date) - 1 ) + @@DATEFIRST ) % 7) IN (5)

           THEN @Current_date + 3

   ELSE @Current_date + 1 END AS next_business_date

2. Check today is business day or not in SQL server.

    SELECT (CASE

        WHEN (((DATEPART(DW,  GETDATE()) - 1 ) + @@DATEFIRST ) % 7) IN (0,6)

        THEN 0

        ELSE 1

      END) AS is_business_day

Reduce NULL value space in SQL server using SPARSE

 Microsoft introduced a new feature called SPARSE in SQL server 2008.This will help to reduce the space of column having high proportion of NULL values. It will help optimizing the SQL storage usage.

 

Where we can use this SPARSE?

              This can be only used column has a high percentage of NULL value in it. Let’s see an example, if you are storing data in fixed column length like int or bigint, once you save NULL in bigint its consume 8 bytes and most of the data are NULL in that column it should be huge storage space based on its data volume. So this can be resolved by creating SPARSE column.

 

CREATE TABLE Emp_table

( 

       ID int IDENTITY (1,1),

       First_Name VARCHAR(50) NULL,

       Last_Name VARCHAR(50) NULL,

       Emp_tagId BIGINT SPARSE NULL

)ON [PRIMARY]

 

From the above script, Emp_tagId is the SPARSE column created to eliminate storage space used by NULL, It will take zero storage space for NULL values

Where we can’t use SPARSE?

       If your column contain less NULL value or it is saving less than 50% of record NULL then it is not good to have use SPARSE because SPARS column consume extra 4 bytes than declared size,it is storing in special structure. Let assume in above example 70% Emp_tagId consists data and rest of them are non-NULL value then it will take total 12 bytes to save non-NULL values, Means 8 bytes for non-null value and 4 bytes for SPARSE.


Thursday, February 27, 2020

SQL Server Transactions Per Day

This post can help you in capturing SQL Server Transactions per day. Sometimes we need to capture the average number of transactions per day / hour / minute. Below is the T-SQL script that can help you to capture the SQL Server Transactions per day. Below script returns two result sets:
  1. Retrieves the total transactions occurred in SQL Server Instance since last restart
  2. Database Wise Average Transactions since last restart

T-SQL to capture SQL Server Transactions per day:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/************************************************************/
/******* SQL Server Transactions Per Day / Hour / Min *******/
/******* Tested : SQL Server 2008 R2, 2012, 2014 ************/
/******* Author : udayarumilli.com **************************/
/************************************************************/
DECLARE @Days SMALLINT,
@Hours INT,
@Minutes BIGINT,
@Restarted_Date DATETIME;
 
/*** Capture the SQL Server instance last restart date ***/
/*** We will gte the Tempdb creation date ***/
SELECT  @Days = DATEDIFF(D, create_date, GETDATE()),
@Restarted_Date = create_date
FROM    sys.databases
WHERE   database_id = 2;
 
/*** Prepare Number of Days and Hours Since the last SQL Server restart ***/
SELECT @Days = CASE WHEN @Days = 0 THEN 1 ELSE @Days END;
SELECT @Hours = @Days * 24;
SELECT @Minutes = @Hours * 60;
 
 
/*** Retrieve the total transactions occurred in SQL Server Instance since last restart ***/
SELECT  @Restarted_Date AS 'Last_Restarted_On',
@@SERVERNAME AS 'Instance_Name',
cntr_value AS 'Total_Trans_Since_Last_Restart',
cntr_value / @Days AS 'Avg_Trans_Per_Day',
cntr_value / @Hours AS 'Avg_Trans_Per_Hour',
cntr_value / @Minutes AS 'Avg_Trans_Per_Min'
FROM    sys.dm_os_performance_counters
WHERE   counter_name = 'Transactions/sec'
        AND instance_name = '_Total';
 
 
/*** Database Wise Average Transactions since last restart ***/
SELECT  @Restarted_Date AS 'Last_Restarted_On',
@@SERVERNAME AS 'Instance_Name',
instance_name AS 'Database_Name',
cntr_value AS 'Total_Trans_Since_Last_Restart',
cntr_value / @Days AS 'Avg_Trans_Per_Day',
cntr_value / @Hours AS 'Avg_Trans_Per_Hour',
cntr_value / @Minutes AS 'Avg_Trans_Per_Min'
FROM    sys.dm_os_performance_counters
WHERE   counter_name = 'Transactions/sec'
        AND instance_name <> '_Total'
ORDER BY cntr_value DESC;



Here is the script file: SQL_Server_Transactions_Per_Day
These are the average values. To get the exact transaction details we can automate the capture process:
  • Create a table to capture the transaction counts since last restart
  • Create a stored procedure to capture the transactions since the last restart
  • Schedule a job to execute the procedure on hourly basis
  • Write a query to capture the hourly differences