Get last 10 execution time of a query in Sql Server 2012 - sql

With this query I'm getting the top 10 slow queries in Sql Server.
SELECT TOP 20
SUBSTRING(qt.text, (qs.statement_start_offset/2)+1,
((CASE qs.statement_end_offset WHEN -1 THEN DATALENGTH(qt.text)
ELSE qs.statement_end_offset
END - qs.statement_start_offset)/2)+1),
qs.execution_count,
qs.total_logical_reads, qs.last_logical_reads,
qs.min_logical_reads, qs.max_logical_reads,
qs.total_elapsed_time, qs.last_elapsed_time,
qs.min_elapsed_time, qs.max_elapsed_time,
qs.last_execution_time,
qp.query_plan
FROM
sys.dm_exec_query_stats qs
CROSS APPLY
sys.dm_exec_sql_text(qs.sql_handle) qt
CROSS APPLY
sys.dm_exec_query_plan(qs.plan_handle) qp
WHERE
qt.encrypted = 0
ORDER BY
qs.total_logical_reads DESC
What I want to do is finding each queries last 10 execution time.
Or an average execution period in a day makes me glad.

You can create snapshots of your database procedure executions at certain period of time and then you can compare them. Use the sql in order to insert into table every snapshot.
SELECT
getDAte() as SnapshotDate,
s.database_id,
s.[plan_handle],
s.[object_id],
s.last_execution_time,
s.execution_count,
s.total_worker_time,
s.last_worker_time,
s.min_worker_time,
s.max_worker_time,
s.total_physical_reads,
s.last_physical_reads,
s.min_physical_reads,
s.max_physical_reads,
s.total_logical_writes,
s.last_logical_writes,
s.min_logical_writes,
s.max_logical_writes,
s.total_logical_reads,
s.last_logical_reads,
s.min_logical_reads,
s.max_logical_reads,
s.total_elapsed_time,
s.last_elapsed_time,
s.min_elapsed_time,
s.max_elapsed_time
FROM sys.dm_exec_procedure_stats AS s
WHERE s.database_id NOT IN
(
DB_ID('master'),
DB_ID(N'tempdb'),
DB_ID(N'model'), DB_ID(N'msdb'),
32767 -- RESOURCE db
) ;

If you want to check that is running slowly and why, check Standard reports in SSMS.

Related

Dapper QueryMultiple shows all queries run multiple times on DB

When using QueryMultiple from dapper, are all of the queries run multiple times on the DB?
.Net core code example:
var query1 = "select * from [User]";
var query2 = "select * from UserRole";
var multiQuery = $"{query1}; {query2}";
using (var multi = await _dbConnection.QueryMultipleAsync(multiQuery))
{
var userResponse = multi.Read<UserResponse>();
var userRoleResponse = multi.Read<UserRoleResponse>();
//DO SOMETHING
}
When I look at the queries run on the DB, I see the following:
Time
Query
2021-11-12 17:17:47.673
select * from [User]; select * from UserRole
2021-11-12 17:17:47.673
select * from [User]; select * from UserRole
SQL query to see latest queries in DB:
SELECT top 10 deqs.last_execution_time AS [Time], dest.text AS [Query]
FROM sys.dm_exec_query_stats AS deqs
CROSS APPLY sys.dm_exec_sql_text(deqs.sql_handle) AS dest
ORDER BY deqs.last_execution_time DESC
I was expecting to see the following:
Time
Query
2021-11-12 17:17:47.673
select * from [User]
2021-11-12 17:17:47.673
select * from UserRole
Does this mean that Dapper's QueryMultiple is running all queries multiple times?
Just hoping to understand how this works as we are looking at potential performance impacts.
Database is Sql Server.
Does this mean that Dapper's QueryMultiple is running all queries multiple times?
No, you're misreading the DMVs.
sys.dm_exec_query_stats has one row per query, but sys.dm_exec_sql_text returns the whole batch (or stored procedure body), not an individual query. So you must use the statement_start_offset and statement_end_offset to extract the individual query.
Here's the example from the docs:
SELECT TOP 5 query_stats.query_hash AS "Query Hash",
SUM(query_stats.total_worker_time) / SUM(query_stats.execution_count) AS "Avg CPU Time",
MIN(query_stats.statement_text) AS "Statement Text"
FROM
(SELECT QS.*,
SUBSTRING(ST.text, (QS.statement_start_offset/2) + 1,
((CASE statement_end_offset
WHEN -1 THEN DATALENGTH(ST.text)
ELSE QS.statement_end_offset END
- QS.statement_start_offset)/2) + 1) AS statement_text
FROM sys.dm_exec_query_stats AS QS
CROSS APPLY sys.dm_exec_sql_text(QS.sql_handle) as ST) as query_stats
GROUP BY query_stats.query_hash
ORDER BY 2 DESC;

SQL WHERE Clause Execution Order

How is the execution of the WHERE clause in a SQL statement determined?
For example:
This first query executes in 8 seconds.
SELECT c.claimnum,
cd.procedurecode,
cd.charges,
cd.contractamount,
dbo.Fn_getfeeschedamount(cd.pk_claimdetail)
FROM claim c WITH(nolock)
INNER JOIN claimdetail cd WITH(nolock)
ON cd.fk_claim = c.pk_claim
WHERE c.dateprocessed BETWEEN dbo.Fn_datenotime(Getdate()) AND Replace(
Cast(dbo.Fn_datenotime(Getdate()) AS
VARCHAR), '12:00AM', '11:59PM')
ORDER BY c.claimnum
This second query executes in 10 seconds.
SELECT *
FROM (SELECT c.claimnum,
cd.procedurecode,
cd.charges,
cd.contractamount,
dbo.Fn_getfeeschedamount(cd.pk_claimdetail) AS [CalcAmount]
FROM claim c WITH(nolock)
INNER JOIN claimdetail cd WITH(nolock)
ON cd.fk_claim = c.pk_claim
WHERE c.dateprocessed BETWEEN dbo.Fn_datenotime(Getdate()) AND Replace(
Cast(dbo.Fn_datenotime(Getdate())
AS
VARCHAR), '12:00AM',
'11:59PM')) AS
c1
WHERE c1.contractamount <> c1.[calcamount]
ORDER BY c1.claimnum
This third query takes much longer to execute (I didn't wait to see how long; over 4 minutes).
SELECT c.claimnum,
cd.procedurecode,
cd.charges,
cd.contractamount,
dbo.Fn_getfeeschedamount(cd.pk_claimdetail)
FROM claim c WITH(nolock)
INNER JOIN claimdetail cd WITH(nolock)
ON cd.fk_claim = c.pk_claim
WHERE c.dateprocessed BETWEEN dbo.Fn_datenotime(Getdate()) AND Replace(
Cast(dbo.Fn_datenotime(Getdate()) AS
VARCHAR), '12:00AM', '11:59PM')
AND cd.contractamount <> dbo.Fn_getfeeschedamount(cd.pk_claimdetail)
ORDER BY c.claimnum
I am running this on a SQL Server 2016 database.
The first query shows all claims for today with their processed amounts and their recalculated amounts.
The last query was my goal of adding one more condition to my where clause to only show claims where the recalculated amount does not match the amount calculated at processing time.
It appears that in the last query, SQL Server is executing the second part of the where clause before the first causing the query to run much longer.
Is there a way to force SQL Server to execute the first part of the where clause first without having to resort to the second query?

SQL Server query issues

We have a SQL Server 2012 database with our live project including multiple tables and records, Basically We are facing a problem with SQL queries on a table where two same SQL queries. The first SQL query is taking less execution time and second SQL query is getting tremendously slow to execute.
I don't know why it is happening someone could help me to solve this problem?
Our two queries are given below....
First query (taking so much time to execute):
SELECT * FROM (SELECT TOP 10 TrackerResponse.EventName,TrackerResponse.ReceiveTime,ISNull(TrackerResponse.InputStatus,0) AS InputStatus,
TrackerResponse.Latitude,TrackerResponse.Longitude,TrackerResponse.Speed,
TrackerResponse.TrackerID,TrackerResponse.OdoMeter,TrackerResponse.Direction,
UserCar.CarNo FROM TrackerResponse
INNER JOIN UserCar ON (UserCar.TrackerID = TrackerResponse.TrackerID)
WHERE (TrackerResponse.EventName IS NOT NULL AND TrackerResponse.EventName<>'')
AND TrackerResponse.TrackerID = 112 Order By ID DESC) AS Events)
Second query (taking less execution time):
SELECT * FROM (SELECT TOP 10 TrackerResponse.EventName,TrackerResponse.ReceiveTime,ISNull(TrackerResponse.InputStatus,0) AS InputStatus,
TrackerResponse.Latitude,TrackerResponse.Longitude,TrackerResponse.Speed,
TrackerResponse.TrackerID,TrackerResponse.OdoMeter,TrackerResponse.Direction,
UserCar.CarNo FROM TrackerResponse
INNER JOIN UserCar ON (UserCar.TrackerID = TrackerResponse.TrackerID)
WHERE (TrackerResponse.EventName IS NOT NULL AND TrackerResponse.EventName<>'')
AND TrackerResponse.TrackerID = 56 Order By ID DESC) AS Events
I see Both queries are similar with an exception of tracker id..so my best guess would be ,this query might be a victim of Parameter sniffing..
Try using Option(Recompile) like below to see if this is the cause and follow article referred in above link for resolution
SELECT * FROM (SELECT TOP 10 TrackerResponse.EventName,TrackerResponse.ReceiveTime,ISNull(TrackerResponse.InputStatus,0) AS InputStatus,
TrackerResponse.Latitude,TrackerResponse.Longitude,TrackerResponse.Speed,
TrackerResponse.TrackerID,TrackerResponse.OdoMeter,TrackerResponse.Direction,
UserCar.CarNo FROM TrackerResponse
INNER JOIN UserCar ON (UserCar.TrackerID = TrackerResponse.TrackerID)
WHERE (TrackerResponse.EventName IS NOT NULL AND TrackerResponse.EventName<>'')
AND TrackerResponse.TrackerID = 56 Order By ID DESC
option(recompile)
AS Events)

How can I optimize this SQL query? (Solarwinds Orion)

I'm very new to SQL, and still learning. I'm using a reporting tool called Solarwinds Orion, and I'm honestly not sure how specific the query I have written is to the program, so if there's anything in the query that's confusing, let me know and I'll try to figure out if it's specific to the program or not.
The problem with the query I'm running is that it times out after a very long time (maybe an hour) of running. The database I'm using is huge. Unfortunately I don't really know how huge, but I've been told it's huge.
Is there anything I am doing wrong that would have a huge performance impact?
SELECT TOP 10000
Nodes.Caption AS NodeName,
NetflowApplicationSummary.AppName AS Application_Name,
SUM(NetflowApplicationSummary.TotalBytes) AS SUM_of_Bytes_Transferred,
AVG(Case OutBandwidth
When 0 Then 0
Else (NetflowApplicationSummary.TotalBytes/OutBandwidth) * 100
End) AS TEST_PERCENT
FROM
((NetflowApplicationSummary
INNER JOIN Nodes ON (NetflowApplicationSummary.NodeID = Nodes.NodeID))
INNER JOIN InterfaceTraffic ON (Nodes.NodeID = InterfaceTraffic.InterfaceID))
INNER JOIN Interfaces ON (Nodes.NodeID = Interfaces.NodeID)
WHERE
( InterfaceTraffic.DateTime > (GetDate()-30) )
AND
(Nodes.WANCircuit = 1)
GROUP BY Nodes.Caption, NetflowApplicationSummary.AppName
EDIT: I ran COUNT() on each of my tables with the below result.
SELECT COUNT(*) FROM NetflowApplicationSummary # 50671011
SELECT COUNT(*) FROM Nodes # 898
SELECT COUNT(*) FROM InterfaceTraffic # 18000166
SELECT COUNT(*) FROM Interfaces # 3938
# Total : 68,676,013
I really have no idea if 68 million items is a huge database to be honest.
A couple of notes:
The INNER JOIN operator is associative, so get rid of those parenthesis in the FROM clause and let the optimizer figure out the best join order.
You may have an implied cursor from the getdate() function being called for every row. Store the value in a local variable and compare to that.
The resulting SQL should look like this:
DECLARE #Date as datetime = getdate() - 30;
SELECT TOP 10000
Nodes.Caption AS NodeName,
NetflowApplicationSummary.AppName AS Application_Name,
SUM(NetflowApplicationSummary.TotalBytes) AS SUM_of_Bytes_Transferred,
AVG(Case OutBandwidth
When 0 Then 0
Else (NetflowApplicationSummary.TotalBytes/OutBandwidth) * 100
End) AS TEST_PERCENT
FROM NetflowApplicationSummary
INNER JOIN Nodes ON NetflowApplicationSummary.NodeID = Nodes.NodeID
INNER JOIN InterfaceTraffic ON Nodes.NodeID = InterfaceTraffic.InterfaceID
INNER JOIN Interfaces ON Nodes.NodeID = Interfaces.NodeID
WHERE InterfaceTraffic.DateTime > #Date
AND Nodes.WANCircuit = 1
GROUP BY Nodes.Caption, NetflowApplicationSummary.AppName
Also, make sure you have an index on table InterfaceTraffic with a leading field of DateTime. If this doesn't exist you may need to pay the penalty of a first time creation of it.
If this doesn't help, then you may need to post the execution plan where it can be inspected.
Out of interest, also perform a count() on all four tables and post that result, just so members here can make their own assessment of how big your database really is. It is amazing how many non-technical people still think a 1 or 10 GB database is huge, while I run that easily on my workstation!

Currently running queries in SQL Server [duplicate]

This question already has answers here:
List the queries running on SQL Server
(17 answers)
Closed 7 years ago.
Is there a program or a sql query that I can find which SQL queries are being run on an SQL Server 2012? I think there was a tool in earlier version of SQL Server where the actual query content gets displayed or the stored procedure name?
I use the below query
SELECT SPID = er.session_id
,STATUS = ses.STATUS
,[Login] = ses.login_name
,Host = ses.host_name
,BlkBy = er.blocking_session_id
,DBName = DB_Name(er.database_id)
,CommandType = er.command
,ObjectName = OBJECT_NAME(st.objectid)
,CPUTime = er.cpu_time
,StartTime = er.start_time
,TimeElapsed = CAST(GETDATE() - er.start_time AS TIME)
,SQLStatement = st.text
FROM sys.dm_exec_requests er
OUTER APPLY sys.dm_exec_sql_text(er.sql_handle) st
LEFT JOIN sys.dm_exec_sessions ses
ON ses.session_id = er.session_id
LEFT JOIN sys.dm_exec_connections con
ON con.session_id = ses.session_id
WHERE st.text IS NOT NULL
Depending on your privileges, this query might work:
SELECT sqltext.TEXT,
req.session_id,
req.status,
req.command,
req.cpu_time,
req.total_elapsed_time
FROM sys.dm_exec_requests req
CROSS APPLY sys.dm_exec_sql_text(sql_handle) AS sqltext
Ref: http://blog.sqlauthority.com/2009/01/07/sql-server-find-currently-running-query-t-sql
There's this, from SQL Server DMV's In Action book:
The output shows the spid (process identifier), the ecid (this is similar to a thread within the same spid and is useful for identifying queries running in parallel), the user running the SQL, the status (whether the SQL is running or waiting), the wait status (why it’s waiting), the hostname, the domain name, and the start time (useful for determining how long the batch has been running).
The nice part is the query and parent query. That shows, for example, a stored proc as the parent and the query within the stored proc that is running. It has been very handy for me. I hope this helps someone else.
USE master
GO
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SELECT
er.session_Id AS [Spid]
, sp.ecid
, er.start_time
, DATEDIFF(SS,er.start_time,GETDATE()) as [Age Seconds]
, sp.nt_username
, er.status
, er.wait_type
, SUBSTRING (qt.text, (er.statement_start_offset/2) + 1,
((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) + 1) AS [Individual Query]
, qt.text AS [Parent Query]
, sp.program_name
, sp.Hostname
, sp.nt_domain
FROM sys.dm_exec_requests er
INNER JOIN sys.sysprocesses sp ON er.session_id = sp.spid
CROSS APPLY sys.dm_exec_sql_text(er.sql_handle)as qt
WHERE session_Id > 50
AND session_Id NOT IN (##SPID)
ORDER BY session_Id, ecid
here is what you need to install the SQL profiler http://msdn.microsoft.com/en-us/library/bb500441.aspx. However, i would suggest you to read through this one http://blog.sqlauthority.com/2009/08/03/sql-server-introduction-to-sql-server-2008-profiler-2/ if you are looking to do it on your Production Environment.
There is another better way to look at the queries watch this one and see if it helps
http://www.youtube.com/watch?v=vvziPI5OQyE
The tool is called the SQL Server Profiler, it's still part of the standard toolset.
You are talking about SQL Profiler.