- CREATE OR ALTER
- DROP IF EXISTS
Recently I’ve experienced a situation where one of the partition maintenance jobs created a blocking. At this point the database had high t-log usage and backup log was also executing. It was clear some kind of large transaction has occurred during a partition maintenance operation. All inserts into the table which was being partitioning, got blocked too.
MSDN states:
Always keep empty partitions at both ends of the partition range to guarantee that the partition split (before loading new data) and partition merge (after unloading old data) do not incur any data movement. Avoid splitting or merging populated partitions. This can be extremely inefficient, as this may cause as much as four times more log generation, and may also cause severe locking.
ALTER PARTITION FUNCTION (Transact-SQL)
So it is important to select a proper partition key so that when achieving using sliding window concept, it works without impacting users.
Cheers.
When querying sys.dm_exec_requests dmv, you can see the waiting requests and the resource those requests are waiting for. Sample of such values are shown in Figure 1 below.
Figure 1 – List of wait resources
How do you interpret these values? It has the following format in this case: (It is not always the same format. Depending on the values you see in wait_resource the interpretation would be different)
[database id] : [file id] : [page id]
However still the information is not sufficient because knowing the page id does not give much details related to the issue your troubleshooting. So we need to figure it out the table related to the above page. For that you need to use some undocumented DBCC commands. (Please be careful when running them in production system)
You get an output similar to below;
Figure 2 – Output of DBCC PAGE command
Refer the objectId value. That is the object Id of the page belongs to. After that it is simple to find the object name using OBEJCT_NAME() T-SQL function.
Cheers.
As a DBA, identifying blockings and waitings is one of the primary tasks. I searched in the Google but did not find a useful script. So I came up with one and thought to share it with others.
;WITH requests (session_id, start_time, status, blocking_session_id,
database_name,
command, sql_text)
AS (SELECT session_id,
start_time,
status,
blocking_session_id,
Db_name(database_id),
command,
sql_text = Cast(text AS VARCHAR(max))
FROM sys.dm_exec_requests WITH (nolock)
CROSS apply sys.Dm_exec_sql_text (sql_handle)
WHERE status <> 'Background'),
blocking (session_id, start_time, status, blocking_session_id, command,
sql_text, rownum, levelrow)
AS (SELECT r1.session_id,
r1.start_time,
r1.status,
r1.blocking_session_id,
r1.command,
r1.sql_text,
Row_number()
OVER (
ORDER BY r1.session_id),
0 AS LevelRow
FROM requests r1
INNER JOIN requests r2
ON r1.session_id = r2.blocking_session_id
WHERE r1.blocking_session_id = 0
UNION ALL
SELECT r3.session_id,
r3.start_time,
r3.status,
r3.blocking_session_id,
r3.command,
r3.sql_text,
b.rownum,
b.levelrow + 1
FROM requests r3
INNER JOIN blocking b
ON r3.blocking_session_id = b.session_id
WHERE r3.blocking_session_id > 0)
SELECT *
FROM blocking
ORDER BY rownum,
levelrow
Alternatively you can write the output of this to a table as a schedule job and the results can be analyzed later. This is really useful to identify any blocking patterns of the database server and fix them if they persist.
This can happen due to many factors like lack of indexes, out of dates statistics, if it returns a large number of records, etc.
I observed a similar behavior recently in a production environment. The stored procedure had the code similar to the following;
SELECT Col3
FROM dbo.Tab1
WHERE Col1 = @Col1
AND Col2 = @Col2
AND RTRIM(LTRIM(REPLACE(REPLACE(REPLACE(REPLACE(CAST(Comments AS VARCHAR(2000)),'<br />',''),CHAR(10),''),CHAR(13),''),' ',''))) <> ''
Let me give you some background information about this table.
Recently one of colleagues asked, how to format a date value according to the style he wants. His date style is as below;
10/15/13 - 04:11 pm
The immediate solution that came into my mind was the CONVERT function which you can specify the conversion style. He had already worked out a solution which using that function and the code is as below;
SELECT LEFT(Lower(CONVERT (VARCHAR, CURRENT_TIMESTAMP, 1) + ' - ' + RIGHT(
CONVERT (
VARCHAR, CURRENT_TIMESTAMP, 100), 8)), 17)
+ ' '
+ Lower(RIGHT(CONVERT (VARCHAR, CURRENT_TIMESTAMP, 100), 2)) AS
"Date/Time"
However it is bit of complex string concatenation. Wouldn’t there be any simple way of doing it? So after bit of research I found the following code which does the exact same thing that my colleague wants.
DECLARE @d DATETIME = CURRENT_TIMESTAMP;
SELECT Lower(Format(@d, 'MM/dd/yy - hh:mm tt')) AS 'Date/Time'
Using FORMAT function, you can format numeric and date values. It also supports the culture. The syntax is as below;
FORMAT ( value, format [, culture ] )
This post is for SQL Server Database Administrators who have find difficulty in some situations when identifying slow running queries. The DBAs who work in production environment specially might have faced situations where users or other production monitoring teams complaining that suddenly they see a slowness in their systems. The “slowness in the system” a very generic term. This could be due to various reasons. Such as;
As a DBA, it is a responsibility to make sure everything is clear in database perspective. Before start troubleshooting the broader phenomena, it is necessary to ask few questions to shed some light into the dark area. Below questions might be useful;
One of my colleagues asked me a question about a simple T-SQL query which uses table alias. See the below T-SQL code;
USE AdventureWorks2012
GO
SELECT E.loginID,HumanResources.Employee.JobTitle FROM HumanResources.Employee E
The above query used a table alias “E” and in SELECT list one column refers with table alias while the other column referring full table name. Seems like technically correct query. However the query returned the following error.
Msg 4104, Level 16, State 1, Line 2
The multi-part identifier "HumanResources.Employee.JobTitle" could not be bound.
As per the error message, use of table name, “HumanResources.Employee” to refer JobTitle column is incorrect. When you remove HumanResources.Employee in the SELECT list then the query works fine.
The theory behind this is when you have a table alias, it logical rename the table to table alias. So if you want to refer the table in the query, it needs to use table alias instead of the actual table name.
Relational algebra explains this more clearly.
The relevant operator for table alias in relational algebra (RA) is RENAME. As SQL derived from RA it is always better to learn RA before learning SQL.
There are several ways to get database sizes in a server. Following three system tables has the information to get database sizes.
sys.sysfiles
sys.database_files
sys.dm_db_file_space_usage
You also can use following system stored procedure.
exec sp_spaceused
However the easiest way is to use SP_HELPDB system stored procedure. Below script used that SP to get the database sizes in a server.
create table #spdbdesc
(
dbname sysname,
dbsize nvarchar(13) null,
owner sysname null,
dbid smallint primary key,
created nvarchar(11),
dbdesc nvarchar(600) null,
cmptlevel tinyint
)
INSERT INTO #spdbdesc
exec SP_HELPDB
SELECT *
FROM #spdbdesc
Some times DBAs want to generate test data to test some applications designed and developed by themselves. I have faced many situations like this in past. Recently also I had to generate some test data to test one of my research projects. Below is the ERD of the application. It is just four tables.
It is important to know what is currently executing in SQL Server at any given time. You may need this for troubleshooting purposes. The below query is useful in such occasions;
SELECT sqltext.TEXT,
req.session_id,
req.status,
req.command,
req.cpu_time,
req.total_elapsed_time,
s.login_name,
s.host_name,
req.wait_type,
req.wait_resource,
SUBSTRING(sqltext.text, (req.statement_start_offset/2)+1,
((CASE req.statement_end_offset
WHEN -1 THEN DATALENGTH(sqltext.text)
ELSE req.statement_end_offset
END - req.statement_start_offset)/2) + 1) AS statement_text,
req.plan_handle,
sqltext.text
FROM sys.dm_exec_requests req
INNER JOIN sys.dm_exec_sessions s
ON req.session_id=s.session_id
CROSS APPLY sys.dm_exec_sql_text(sql_handle) AS sqltext
ORDER BY req.cpu_time DESC
I was analyzing IO stats in one of our SQL Servers and noticed that IO latency (Read / Write) are very high. As a rule of thumb, we know tha...