1 Jul, 2022

Investigating SQL Server performance issues

Had an interesting morning trouble shooting SQL Server performance issues for a client.

They had SSMS version 12, so we used the ‘Activity Monitor’ tool. To access the tool, right click on the server name in SQL Server Management Studio and you’ll see ‘Activity Monitor’.

Looking at the long running queries tab for about 15 minutes, we identified five queries which were each taking between 40-50 seconds.

SQL Server Activity Monitor

On further inspection, some of the queries were joining tables of 2.5million rows. We therefore added some clustered indexes to try and speed up the queries. This managed to reduce the query down to 15 seconds, but we in the end we decided to ask the software vendor if they could rewrite the query, or break it into several queries, to try and improve performance further.

17 Mar, 2014

Script to get row counts for tables in a database

Script to get row counts for tables in a database

This is a great little piece of SQL which does something really useful. It displays the tables in a database together with the row counts for each, in descending order of size. This is useful if you are performing some database maintenance and want to know which tables are using the most space.

Note : is_ms_shipped = 0 is used so that system tables are not included.

SELECT objs.name,
part_stats.row_count
FROM sys.indexes AS indxs
INNER JOIN sys.dm_db_partition_stats AS part_stats ON indxs.OBJECT_ID = part_stats.OBJECT_ID
INNER JOIN sys.objects AS objs ON indxs.OBJECT_ID = objs.OBJECT_ID
AND indxs.index_id = part_stats.index_id
WHERE indxs.index_id < 2 AND objs.is_ms_shipped = 0 ORDER BY part_stats.row_count desc

17 Mar, 2014

SQL – joining a table with an aggregated query

Recently we were asked how to join a table with an aggregated query from another table.

This is actually quite easy – you just embed the aggregated query from the second table into the second part of the query. An example is shown below.

select customer.*, orderstotal.totalsales
from customer join
(select orders.customerid, sum(orders.totalvalue) as totalsales
from orders
group by orders.customerid
having sum(orders.totalvalue) > 100
) orderstotal
on customer.customerid=orderstotal.customerid
where customer.f7 = ‘France’

This will then return all records for customers from ‘France’, where the sales order total is greater than 100. The query will show all customer fields and their total sales value. A query of this type gives considerable flexibility. The join could also be changed to a left outer so that all customers are shown, even if they have no sales.

17 Mar, 2014

SQL Server Backup Script (Powershell)

We’re often asked for some hints for a SQL Server Backup Script. The bare bones of one is shown in this post. This script has the following steps:
1. Remove all previous backup items more than 10 days old
2. Remove the current backup
3. Run the backup
4. Copy the backup to a datestamped file, so that multiple backups exist.
5. Compress the backup file
===================================================

# Step 1 – Remove all items more than 10 days old in the backup media
Add-Type -Assembly “System.IO.Compression.FileSystem” ;
$limit = (Get-Date).AddDays(-10)
$path = “G:”
Get-ChildItem -Path $path -Attributes !Directory+!System -Force | Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $limit } | Remove-Item -Force

# Step 2 – Remove previous mydatabasename.bak and zip file
Remove-Item “G:\Current\mydatabasename.*” -Recurse
Remove-Item “G:\mydatabasename.*” -Recurse

# Step 3 – Run the backup
#Sqlcmd -S 127.0.0.1 -U myusername -P mypassword -Q “BACKUP DATABASE mydatabasename TO EXTERNALDISK”

$backupFolder = ‘…’
$additionToName = ‘…’

$user = myusername
$pass = ‘mypassword’
$inst = ‘127.0.0.1’
$db = ‘mydatabasename’
$file = “$backupFolder${db}_db_$additionToName.bak”

$sql = @”
USE $db;
GO
BACKUP DATABASE $db TO EXTERNALDISK;
GO
“@

Invoke-Sqlcmd -QueryTimeout 3600 -Query $sql -ServerInstance $inst –Username $user –Password $pass

# Step 4 – Copy the backup to a date-stamped filename
$fileName = “G:\Current\mydatabasename.bak”
$fileObj = get-item $fileName

# Get the date
$DateStamp = get-date -uformat “%Y-%m-%d@%H-%M-%S”

$extOnly = $fileObj.extension

if ($extOnly.length -eq 0) {
$nameOnly = $fileObj.Name
copy-item “$fileObj” “$nameOnly-$DateStamp”
}
else {
$nameOnly = $fileObj.Name.Replace( $fileObj.Extension,”)
copy-item “$fileName” “G:\$nameOnly-$DateStamp$extOnly”
}

# Step 5 – Compress the backup file
[System.IO.Compression.ZipFile]::CreateFromDirectory(“G:\Current”, “G:\mydatabasename.zip”) ;

[Environment]::Exit(1)