【发布时间】:2021-05-27 04:39:26
【问题描述】:
我已经编写了 3 个存储过程,并且在 SQL Server 中执行时都运行良好。但是,当我在 Visual Studio 2012 中执行它们时,它们只是“旋转”、创建锁等。有什么想法吗?
这是其中之一。另一种是从基于相同 SQL 的内联视图中选择值,而不是插入到 #temp
@StartDate As DateTime,
@EndDate As DateTime,
@EmployeeCode As VarChar(50) = NULL
AS
BEGIN
SET NOCOUNT ON;
select * into #temp
from
(SELECT e.Code AS EMPLOYEE_ID,
e.FirstName AS FIRST_NAME,
e.LastName AS LAST_NAME,
ec1.TransactionDate AS DATE_OF_SHIFT,
ou.Code AS DEPT_UNIT_CODE,
CASE
WHEN ec1.Classification = '1' THEN
MIN(ec1.TransactionDate)
END AS CLOCK_IN,
CASE
WHEN ec2.Classification = '2' THEN
MAX(ec2.TransactionDate)
END AS CLOCK_OUT,
pc.code,
epb.hourvalue
FROM APIHealthcare_History_Live.dbo.Employee e (nolock)
JOIN APIHealthcare_Live.dbo.EmployeeClocking ec1 (nolock)
ON ec1.EmployeeID = e.ID
JOIN APIHealthcare_Live.dbo.EmployeeClocking ec2 (nolock)
ON ec1.OutClockingGuid = ec2.Guid
JOIN APIHealthcare_Live.dbo.OrganizationUnit ou (nolock)
ON ec1.OrganizationUnitID = ou.ID
LEFT JOIN APIHealthcare_Live.dbo.EmployeePremiumBucket epb (nolock)
ON ec1.Guid = epb.TransactionGuid
JOIN APIHealthcare_Live.dbo.PayCode pc (nolock)
ON epb.PayCodeID = pc.ID
JOIN APIHealthcare_Live.dbo.PayGroupInstance pgi (nolock)
ON pgi.ID = epb.PayGroupInstanceID
WHERE
ec1.transactiondate between @StartDate and @EndDate
and epb.PaymentClassification = '1'
AND e.code = @EmployeeCode
AND e.ArchiveTaskID =
(
SELECT MAX(e2.ArchiveTaskID)
FROM APIHealthcare_History_Live.dbo.Employee e2 (NOLOCK)
WHERE e2.ID = e.ID
)
GROUP BY e.Code,
e.FirstName,
e.LastName,
ec1.TransactionDate,
ou.Code,
ec1.Classification,
ec2.Classification,
pc.code,
epb.hourvalue
UNION
SELECT e.Code AS EMPLOYEE_ID,
e.FirstName AS FIRST_NAME,
e.LastName AS LAST_NAME,
ec1.TransactionDate AS DATE_OF_SHIFT,
ou.Code AS DEPT_UNIT_CODE,
CASE
WHEN ec1.Classification = '1' THEN
MIN(ec1.TransactionDate)
END AS CLOCK_IN,
CASE
WHEN ec2.Classification = '2' THEN
MAX(ec2.TransactionDate)
END AS CLOCK_OUT,
pc.code,
epb.hourvalue
FROM APIHealthcare_History_Live.dbo.Employee e (nolock)
JOIN APIHealthcare_History_Live.dbo.EmployeeClocking ec1 (nolock)
ON ec1.EmployeeID = e.ID
JOIN APIHealthcare_History_Live.dbo.EmployeeClocking ec2 (nolock)
ON ec1.OutClockingGuid = ec2.Guid
JOIN APIHealthcare_History_Live.dbo.OrganizationUnit ou (nolock)
ON ec1.OrganizationUnitID = ou.ID
LEFT JOIN APIHealthcare_History_Live.dbo.EmployeePremiumBucket epb (nolock)
ON ec1.Guid = epb.TransactionGuid
JOIN APIHealthcare_History_Live.dbo.PayCode pc (nolock)
ON epb.PayCodeID = pc.ID
JOIN APIHealthcare_History_Live.dbo.PayGroupInstance pgi (nolock)
ON pgi.ID = epb.PayGroupInstanceID
WHERE
ec1.transactiondate between @StartDate and @EndDate
and epb.PaymentClassification = '1'
AND e.code = @EmployeeCode
AND e.ArchiveTaskID =
(
SELECT MAX(e2.ArchiveTaskID)
FROM APIHealthcare_History_Live.dbo.Employee e2 (NOLOCK)
WHERE e2.ID = e.ID
)
AND ou.ArchiveTaskID =
(
SELECT MAX(ou2.ArchiveTaskID)
FROM APIHealthcare_History_Live.dbo.OrganizationUnit ou2 (NOLOCK)
WHERE ou2.ID = ou.ID
)
AND pc.ArchiveTaskID =
(
SELECT MAX(pc2.ArchiveTaskID)
FROM APIHealthcare_History_Live.dbo.PayCode pc2 (NOLOCK)
WHERE pc2.ID = pc.ID
)
GROUP BY e.Code,
e.FirstName,
e.LastName,
ec1.TransactionDate,
ou.Code,
ec1.Classification,
ec2.Classification,
pc.code,
epb.hourvalue) as X
select EMPLOYEE_ID,
FIRST_NAME,
LAST_NAME,
DATE_OF_SHIFT,
DEPT_UNIT_CODE,
CLOCK_IN,
CLOCK_OUT,
code,
sum(hourvalue) as Hours
from #temp
group by EMPLOYEE_ID,
FIRST_NAME,
LAST_NAME,
DATE_OF_SHIFT,
DEPT_UNIT_CODE,
CLOCK_IN,
CLOCK_OUT,
CODE
Order by CLOCK_OUT
END
这是另一个。
@StartDate As DateTime,
@EndDate As DateTime,
@EmployeeCode As VarChar(50) = NULL
AS
BEGIN
SET NOCOUNT ON;
select EMPLOYEE_ID,
FIRST_NAME,
LAST_NAME,
DATE_OF_SHIFT,
DEPT_UNIT_CODE,
CLOCK_IN,
CLOCK_OUT,
code,
sum(hourvalue) as Hours
from
(
SELECT e.Code AS EMPLOYEE_ID,
e.FirstName AS FIRST_NAME,
e.LastName AS LAST_NAME,
ec1.TransactionDate AS DATE_OF_SHIFT,
ou.Code AS DEPT_UNIT_CODE,
CASE
WHEN ec1.Classification = '1' THEN
MIN(ec1.TransactionDate)
END AS CLOCK_IN,
CASE
WHEN ec2.Classification = '2' THEN
MAX(ec2.TransactionDate)
END AS CLOCK_OUT,
pc.code,
epb.hourvalue
FROM APIHealthcare_History_Live.dbo.Employee e
JOIN APIHealthcare_Live.dbo.EmployeeClocking ec1
ON ec1.EmployeeID = e.ID
JOIN APIHealthcare_Live.dbo.EmployeeClocking ec2
ON ec1.OutClockingGuid = ec2.Guid
JOIN APIHealthcare_Live.dbo.OrganizationUnit ou
ON ec1.OrganizationUnitID = ou.ID
LEFT JOIN APIHealthcare_Live.dbo.EmployeePremiumBucket epb
ON ec1.Guid = epb.TransactionGuid
JOIN APIHealthcare_Live.dbo.PayCode pc
ON epb.PayCodeID = pc.ID
JOIN APIHealthcare_Live.dbo.PayGroupInstance pgi
ON pgi.ID = epb.PayGroupInstanceID
WHERE ec1.transactiondate between @StartDate and @EndDate
and epb.PaymentClassification = '1'
AND e.code = @EmployeeCode
AND e.ArchiveTaskID =
(
SELECT MAX(e2.ArchiveTaskID)
FROM APIHealthcare_History_Live.dbo.Employee e2 (NOLOCK)
WHERE e2.ID = e.ID
)
GROUP BY e.Code,
e.FirstName,
e.LastName,
ec1.TransactionDate,
ou.Code,
ec1.Classification,
ec2.Classification,
pc.code,
epb.hourvalue
UNION
SELECT e.Code AS EMPLOYEE_ID,
e.FirstName AS FIRST_NAME,
e.LastName AS LAST_NAME,
ec1.TransactionDate AS DATE_OF_SHIFT,
ou.Code AS DEPT_UNIT_CODE,
CASE
WHEN ec1.Classification = '1' THEN
MIN(ec1.TransactionDate)
END AS CLOCK_IN,
CASE
WHEN ec2.Classification = '2' THEN
MAX(ec2.TransactionDate)
END AS CLOCK_OUT,
pc.code,
epb.hourvalue
FROM APIHealthcare_History_Live.dbo.Employee e
JOIN APIHealthcare_History_Live.dbo.EmployeeClocking ec1
ON ec1.EmployeeID = e.ID
JOIN APIHealthcare_History_Live.dbo.EmployeeClocking ec2
ON ec1.OutClockingGuid = ec2.Guid
JOIN APIHealthcare_History_Live.dbo.OrganizationUnit ou
ON ec1.OrganizationUnitID = ou.ID
LEFT JOIN APIHealthcare_History_Live.dbo.EmployeePremiumBucket epb
ON ec1.Guid = epb.TransactionGuid
JOIN APIHealthcare_History_Live.dbo.PayCode pc
ON epb.PayCodeID = pc.ID
JOIN APIHealthcare_History_Live.dbo.PayGroupInstance pgi
ON pgi.ID = epb.PayGroupInstanceID
WHERE ec1.transactiondate between @StartDate and @EndDate
and epb.PaymentClassification = '1'
AND e.code = @EmployeeCode
AND e.ArchiveTaskID =
(
SELECT MAX(e2.ArchiveTaskID)
FROM APIHealthcare_History_Live.dbo.Employee e2 (NOLOCK)
WHERE e2.ID = e.ID
)
AND ou.ArchiveTaskID =
(
SELECT MAX(ou2.ArchiveTaskID)
FROM APIHealthcare_History_Live.dbo.OrganizationUnit ou2 (NOLOCK)
WHERE ou2.ID = ou.ID
)
AND pc.ArchiveTaskID =
(
SELECT MAX(pc2.ArchiveTaskID)
FROM APIHealthcare_History_Live.dbo.PayCode pc2 (NOLOCK)
WHERE pc2.ID = pc.ID
)
GROUP BY e.Code,
e.FirstName,
e.LastName,
ec1.TransactionDate,
ou.Code,
ec1.Classification,
ec2.Classification,
pc.code,
epb.hourvalue) as X
group by
EMPLOYEE_ID,
FIRST_NAME,
LAST_NAME,
DATE_OF_SHIFT,
DEPT_UNIT_CODE,
CLOCK_IN,
CLOCK_OUT,
code
order by date_of_shift, code
END
【问题讨论】:
-
有一些“影响计划的选项”会改变 SQL Query Planner 创建计划以执行查询的方式,这些可能会导致执行完全相同的 SQL 代码的不同客户端之间的主要性能差异。比较 ANSI_NULLS、ANSI_PADDING、ANSI_WARNINGS、ARITHABORT、CONCAT_NULL_YIELDS_NULL 和 QUOTED_IDENTIFIER 的 SSMS 和 Visual Studio 设置。通读 Erland Sommarskog 的优秀文章 Slow in the Application, Fast in SSMS? Understanding Performance Mysteries 了解为什么会发生这种情况。
-
一个非常基本的存储过程
SELECT 1会导致同样的问题吗?我建议您逐步添加代码,直到找到导致问题的部分。或使用sp_whoisactive确定导致问题的等待类型。
标签: sql-server visual-studio stored-procedures