Wednesday, July 24, 2024

Find out which database is using the most IO

Find out which database is using the most IO

 

When there are many databases on one drive and you need to find out  which one is causing IO issue or slowing down others then you can use below scripts to find out problematic databases. You can either separate them or fix long running queries  to fix IO issues.

 

--Queries taking longest elapsed time:
SELECT TOP 10
qs.total_elapsed_time / qs.execution_count / 1000000.0 AS average_seconds,
qs.total_elapsed_time / 1000000.0 AS total_seconds,
qs.execution_count,
SUBSTRING (qt.text,qs.statement_start_offset/2,
(CASE WHEN qs.statement_end_offset = -1
THEN LEN(CONVERT(NVARCHAR(MAX), qt.text)) * 2
ELSE qs.statement_end_offset END - qs.statement_start_offset)/2) AS individual_query,
o.name AS object_name,
DB_NAME(qt.dbid) AS database_name
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt
LEFT OUTER JOIN sys.objects o ON qt.objectid = o.object_id
where qt.dbid = DB_ID()
ORDER BY average_seconds DESC;

--Queries doing most I/O:

SELECT TOP 10
(total_logical_reads + total_logical_writes) / qs.execution_count AS average_IO,
(total_logical_reads + total_logical_writes) AS total_IO,
qs.execution_count AS execution_count,
SUBSTRING (qt.text,qs.statement_start_offset/2,
(CASE WHEN qs.statement_end_offset = -1
THEN LEN(CONVERT(NVARCHAR(MAX), qt.text)) * 2
ELSE qs.statement_end_offset END - qs.statement_start_offset)/2) AS indivudual_query,
o.name AS object_name,
DB_NAME(qt.dbid) AS database_name
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) as qt
LEFT OUTER JOIN sys.objects o ON qt.objectid = o.object_id
where qt.dbid = DB_ID()
ORDER BY average_IO DESC;

-------------The most busiest db find the most read write and io_stall

select db_name(mf.database_id) as databaseName, mf.physical_name,
       num_of_reads, num_of_bytes_read, io_stall_read_ms, num_of_writes,
       num_of_bytes_written, io_stall_write_ms, io_stall,size_on_disk_bytes
from sys.dm_io_virtual_file_stats(null,null) as divfs
         join sys.master_files as mf
              on mf.database_id = divfs.database_id
                 and mf.file_id = divfs.file_id
                  order by num_of_reads desc


 

Tuesday, July 23, 2024

Powershell - Start or Stop SQL service on remote server

 You can use below script to start and stop remote SQL services.


* Just for one computer

(Get-Service -ComputerName YOURCOMPUTERNAME -Name 'SQLAgent').Stop()
(Get-Service -ComputerName YOURCOMPUTERNAME -Name 'SQLAgent').Start() 


* For multiple computer

$ServerList = Get-Content "DRIVE\ServerNames.txt"

ForEach ($ServerName in $ServerList)
{
    Write-Host $ServerName
    (Get-Service -ComputerName YOURCOMPUTERNAME -Name 'SQLAgent').Stop()
    (Get-Service -ComputerName YOURCOMPUTERNAME -Name 'SQLAgent').Start()

}

Powershell - Run SQL Scripts on Multiple Servers

 You must need SqlServer module is the current PowerShell module to use below script.

The SqlServer module comes with:

  • PowerShell Providers, which enables a simple navigation mechanism similar to file system paths. You can build paths similar to file system paths, where the drive is associated with a SQL Server management object model, and the nodes are based on the object model classes. You can then use familiar commands such as cd (alias for Set-Location) and dir (alias for Get-ChildItem) to navigate the paths similar to the way you navigate folders in a command prompt window. You can use other commands, such as ren (alias for Rename-Item) or del (alias for Remove-Item), to perform actions on the nodes in the path.

  • A set of cmdlets that support actions such as running a sqlcmd script containing Transact-SQL or XQuery statements.

  • The AS provider and cmdlets, which before they were installed separately.

     

    YOU NEED TO  PUT ALL SQL SERVER INSTANCE NAMES IN INSTANCENAME.txt file in order to run below script. I use  this scripts a lot to update or pull many information from different servers.

     

    $ServerList = Get-Content "DRIVE\InstanceName.txt"
    $SourceDatabase = "master"
    $Script1 = "select @@servername"

    ForEach ($ServerName in $ServerList)
    {
        Write-Host $ServerName
        invoke-sqlcmd -ServerInstance $ServerName -Database $SourceDatabase -Query $Script1

    }

     

     Comment your thought regarding this script. Let me know if you need to generate any scripts for your project I will be happy to help you out.