The following query displays the top 10 procedures that use the most memory and disk IO on your system. The query further breaks down the logical vs physical reads. Physical reads are the ones that actually touch the disk, logical reads are the ones that read from memory. The ones that read from disk more often will be the ones that are most likely executed less. Fixing the following queries will most likely alleviate your server’s resources quite a bit. [cc lang=”sql”] SELECT TOP 10 ObjectName = OBJECT_SCHEMA_NAME(qt.objectid,dbid) + ‘.’ + OBJECT_NAME(qt.objectid, qt.dbid) ,DiskReads = qs.total_physical_reads — The worst reads, disk reads ,MemoryReads = qs.total_logical_reads –Logical Reads are memory reads ,ReadsPerExecution = NULLIF(qs.total_physical_reads + qs.total_logical_reads,0) / qs.execution_count ,Executions = qs.execution_count ,CPUTime = qs.total_worker_time ,DiskWaitAndCPUTime = qs.total_elapsed_time ,MemoryWrites = qs.max_logical_writes ,DateCached = qs.creation_time ,DatabaseName = DB_Name(qt.dbid) ,LastExecutionTime = qs.last_execution_time FROM sys.dm_exec_query_stats AS qs CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS qt ORDER BY qs.total_physical_reads + qs.total_logical_reads DESC [/cc]
Continue reading ...
The following code generates the same information found in sp_who2, along with some additional troubleshooting information. It also contains the SQL Statement being run, so instead of having to execute a separate DBCC INPUTBUFFER, the statement being executed is shown in the results. Unlike sp_who2, this custom sp_who3 only shows sessions that have a current executing request. What is also shown is the reads and writes for the current command, along with the number of reads and writes for the entire SPID. It also shows the protocol being used (TCP, NamedPipes, or Shared Memory). The lead blocker below will show in the BlkBy column as -1. [cc lang=”sql”] USE [master] GO CREATE PROCEDURE [dbo].[sp_who3] AS BEGIN SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; SELECT SPID = er.session_id ,BlkBy = CASE WHEN lead_blocker = 1 THEN -1 ELSE er.blocking_session_id END ,ElapsedMS = er.total_elapsed_time ,CPU = er.cpu_time ,IOReads = er.logical_reads + er.reads ,IOWrites = er.writes ,Executions = ec.execution_count ,CommandType = er.command ,LastWaitType = er.last_wait_type ,ObjectName = OBJECT_SCHEMA_NAME(qt.objectid,dbid) + ‘.’ + OBJECT_NAME(qt.objectid, qt.dbid) ,SQLStatement = SUBSTRING ( qt.text, er.statement_start_offset/2, CASE WHEN ( CASE WHEN er.statement_end_offset = -1 THEN LEN(CONVERT(nvarchar(MAX), qt.text)) * 2 ELSE er.statement_end_offset END – er.statement_start_offset / 2 ) < 0 THEN 0 ELSE CASE WHEN er.statement_end_offset = -1 THEN LEN(CONVERT(nvarchar(MAX), qt.text)) * 2 ELSE er.statement_end_offset END - er.statement_start_offset / 2 END ) ,STATUS = ses.STATUS ,[Login] = ses.login_name ,Host = ses.host_name ,DBName = DB_Name(er.database_id) ,StartTime = er.start_time ,Protocol = con.net_transport ,transaction_isolation = CASE ses.transaction_isolation_level WHEN 0 THEN 'Unspecified' WHEN 1 THEN 'Read […]
Continue reading ...
When using OPENQUERY you will sometimes want to make calls to the same server you are working from. The most common reason for this is to query the output of a stored procedure into a temporary table. For that example, follow this link: (Insert Results of Stored Procedure Into Table) Before doing that you will have to create a linked server. You can either create the server programatically: [cc lang=”sql”] EXEC sp_addlinkedserver @server=’LOCALSERVER’, @srvproduct=’SQLSERVER’, @provider=’SQLNCLI’, @datasrc=’SERVERNAMEINSTANCENAME’ [/cc] Or you can create the linked server manually: In SSMS, Expand Server Objects -> Linked Servers -> (Right click on the Linked Server Folder and select “New Linked Server”) The “New Linked Server” Dialog appears. Type in a friendly name that describes your local server (without spaces). I use LOCALSERVER. Provider – Select “Microsoft OLE DB Provider for SQL Server” Product Name – type: SQLSERVER (with no spaces) Datasource – type the SERVERNAMEINSTANCENAME ProviderString – Blank Catalog – Optional (If entered use the default database you will be using) Within the same Dialog on the left menu under “Select a Page”, select Security Select the radio button named “Be made using the login’s current security context” Click OK, and the new linked server is created
Continue reading ...
[cc lang=”sql”] SELECT TOP 10 ‘Procedure’ = qt.text ,DiskReads = qs.total_physical_reads — The worst reads, disk reads ,MemoryReads = qs.total_logical_reads –Logical Reads are memory reads ,Executions = qs.execution_count ,CPUTime = qs.total_worker_time ,DiskWaitAndCPUTime = qs.total_elapsed_time ,MemoryWrites = qs.max_logical_writes ,DateCached = qs.creation_time ,DatabaseName = DB_Name(qt.dbid) ,LastExecutionTime = qs.last_execution_time FROM sys.dm_exec_query_stats AS qs CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS qt ORDER BY qs.max_logical_writes DESC [/cc]
Continue reading ...
Since stored procedures are generally the most efficient way to call and retrieve data, it’s natural to want to encapsulate logic in them and call them when needed. With this use also comes the need to retrieve the data they return. When you already know the datatypes and columns being returned from the procedure, this is a relatively easy task. Let’s start by looking at an example call. [cc lang=”sql”] — Create a sample stored procedure CREATE PROCEDURE GetList AS BEGIN SELECT ListName = ‘MyList’ ,ListNumber = 1 END GO — this table will house our results CREATE TABLE #List ( ListName varchar(25), ListNumber int ) — finally, execute and insert into our table INSERT INTO #List ( ListName, ListNumber ) EXEC dbo.GetList [/cc] That was relatively easy, however dynamically retrieving the result set from a stored procedure without knowing the columns and datatypes returned in advance has historically proven to be a difficult task. Fortunately with the advent of OPENROWSET, our life as developers has become much simpler. Using openrowset is very simple when we do not have procedures that take parameters, However when parameters become involved the game changes, however there is a workaround. In using OPENROWSET we need to turn on the ability to run distributed queries on your server. To enable this is simple, given you have the appropriate permissions. It’s a simple process when we do not have to pass in parameters. [cc lang=”sql”] sp_configure ‘Ad Hoc Distributed Queries’,1 RECONFIGURE WITH OVERRIDE [/cc] Using OPENROWSET […]
Continue reading ...