如何在SP中使用SQL查询获得更好的性能?它有很多内存使用情况。如果您在我的执行面板下面查看,将会发现:
IF NOT EXISTS(SELECT * FROM Common.[CustomerxxxIds] WHERE xyzType = @xyzType AND CustomerId = @CustomerId)[/code]
有大量的内存使用情况。我该如何减少呢?
ALTER PROCEDURE [Common].[SaveCustomerxxxIds]
(
@xyzType NVARCHAR(128),
@CustomerId INT,
@xxxId INT OUTPUT
)
AS
BEGIN
SET NOCOUNT ON;
IF NOT EXISTS(SELECT * FROM Common.[CustomerxxxIds] WHERE xxxType = @xxxType AND CustomerId = @CustomerId)
BEGIN
INSERT INTO Common.[CustomerxxxIds]
([xxxId]
,[CustomerId]
,[xxxType])
VALUES
(0
,@CustomerId
,@xxxType)
END
UPDATE Common.[CustomerxxxIds]
SET [xxxId] = ([xxxId]) + 1
WHERE [xxxType] = @xxxType
AND CustomerId = @CustomerId
SELECT @xxxId = xxxId
FROM Common.[CustomerxxxIds]
WHERE [xxxType] = @xxxType
AND CustomerId = @CustomerId
END
答案 0 :(得分:2)
您可以采取一些措施来避免对表进行“重新读取”以获得输出值。
在插入之后 (插入Common。[CustomerxxxIds])
使用SCOPE_IDxxx()获取新创建的代理密钥。
以上内容仅适用于IDxxx列。根据您的问题,您实际上可能没有IDxxx列。
请参见
https://docs.microsoft.com/en-us/sql/t-sql/functions/scope-idxxx-transact-sql?view=sql-server-2017
.........
通过UPDATE和/或INSERT,您可以使用OUTPUT功能来获取值。
https://docs.microsoft.com/en-us/sql/t-sql/queries/output-clause-transact-sql?view=sql-server-2017
这避免了最后一个select语句(即我所说的“重新读取”),以获得所需的输出值。
显然,完全删除SELECT语句将提高性能。
..
下面是一个简单但完整的罗斯文数据库示例,该示例将OUTPUT用于INSERT和UPDATE
SELECT 'Before' as Looksie, [ShipperID]
,[CompanyName]
,[Phone]
FROM [Northwind].[dbo].[Shippers]
--
DECLARE @MyInsertAuditTable table( AuditShipperID INT,
AuditCompanyName nvarchar(40),
AuditPhone nvarchar(24));
INSERT [Northwind].[dbo].[Shippers] (CompanyName , Phone )
OUTPUT INSERTED.ShipperID, INSERTED.CompanyName, INSERTED.Phone
INTO @MyInsertAuditTable (AuditShipperID, AuditCompanyName , AuditPhone )
SELECT TOP 1
--(SELECT MAX(ShipperID) + 1 from dbo.Shippers )
'Shipper' + LEFT(CONVERT(VARCHAR(38), NEWID()), 12)
, '(555) 555-5555'
FROM sys.objects
--Display the result set of the table variable.
SELECT AuditShipperID, AuditCompanyName, AuditPhone FROM @MyInsertAuditTable;
DECLARE @MyUpdateAuditTable table( AuditShipperID INT,
AuditCompanyName nvarchar(40),
AuditOldPhone nvarchar(24),
AuditNewPhone nvarchar(24));
UPDATE [Northwind].[dbo].[Shippers]
SET Phone = '(777) 555-7777'
OUTPUT inserted.ShipperID, inserted.CompanyName ,
deleted.Phone,
inserted.Phone
INTO @MyUpdateAuditTable ( AuditShipperID, AuditCompanyName, AuditOldPhone , AuditNewPhone)
FROM [Northwind].[dbo].[Shippers] shippers
JOIN @MyInsertAuditTable insAudit on shippers.ShipperID = insAudit.AuditShipperID
SELECT * from @MyUpdateAuditTable
SELECT 'After' as Looksie, [ShipperID]
,[CompanyName]
,[Phone]
FROM [Northwind].[dbo].[Shippers]
--
结果
Looksie ShipperID CompanyName Phone
Before 1 Speedy Express (503) 555-9831
Before 2 United Package (503) 555-3199
Before 3 Federal Shipping (503) 555-9931
..
AuditShipperID AuditCompanyName AuditPhone
9 Shipper3C062D46-EEA (555) 555-5555
...
AuditShipperID AuditCompanyName AuditOldPhone AuditNewPhone
9 Shipper3C062D46-EEA (555) 555-5555 (777) 555-7777
..
Looksie ShipperID CompanyName Phone
After 1 Speedy Express (503) 555-9831
After 2 United Package (503) 555-3199
After 3 Federal Shipping (503) 555-9931
After 9 Shipper3C062D46-EEA (777) 555-7777
答案 1 :(得分:0)
您可以通过将SELECT *
更改为SELECT 1
来实现。可能有帮助
IF NOT EXISTS (SELECT 1 FROM Common.[CustomerxxxIds]
WHERE xyzType = @xyzType AND CustomerId = @CustomerId)
答案 2 :(得分:-1)
尝试一下
ALTER PROCEDURE [Common].[SaveCustomerxxxIds]
(
@xyz NVARCHAR(128),
@CustomerId INT,
@xxxId INT OUTPUT
)
AS
BEGIN
set @xxxId=null
--Get xxxId
SELECT @xxxId=[xxxId] FROM Common.[CustomerxxxIds] WHERE xyz = @xyz AND CustomerId = @CustomerId
--If @xxxId means no record we should insert
if (@xxxId is null)
begin
--When insert we always insert xxxId as 0 then update to one then we collect the value (one) from db and return it.
--Better set value directly as one insert it to DB and return it as one. Instead of insert, update, select
--just insert
set @xxxId = 1
INSERT INTO Common.[CustomerxxxIds]
([xxxId]
,[CustomerId]
,[xyz])
VALUES
(@xxxId
,@CustomerId
,@xyz)
end
else
begin
--If we have the value we add one to it update the record and return it.
--better than update table then select.
--We already have the value we add one to it then update table and return the value we have
set @xxxId+=1
UPDATE Common.[CustomerxxxIds] SET [xxxId] = @xxxId
WHERE [xyz] = @xyz AND CustomerId = @CustomerId
END
end