Ich habe eine Tabelle in SQL Server, die ich von einem Legacy-System geerbt habe, das noch in Produktion ist, die nach dem folgenden Code strukturiert ist. Ich habe einen SP erstellt, um die Tabelle abzufragen, wie im Code unterhalb der Anweisung create beschrieben. Mein Problem ist, dass sporadisch Aufrufe von .NET zu diesem SP sowohl über die Enterprise Library 4 als auch über ein DataReader-Objekt langsam sind. Der SP wird über eine Schleifenstruktur in der Datenschicht aufgerufen, die die Parameter angibt, die zum Zweck des Auffüllens von Benutzerobjekten in den SP gelangen. Es ist auch wichtig zu erwähnen, dass ein langsamer Aufruf nicht bei jedem Durchlauf der Schleifenstruktur stattfinden wird. Es wird in der Regel für die meisten von einem Tag oder mehr in Ordnung sein, und dann zu präsentieren beginnen, was es extrem schwierig macht zu debuggen.Sporadisch langsame Aufrufe von .NET-Anwendung an SQL Server
Die fragliche Tabelle enthält etwa 5 Millionen Zeilen. Zum Beispiel dauern die langsamen Anrufe 10 Sekunden, während die schnellen Anrufe durchschnittlich 0 bis 10 Millisekunden benötigen. Ich habe während der langsamen Anrufe nach blockierenden/blockierenden Transaktionen gesucht, keine wurden gefunden. Ich habe einige benutzerdefinierte Leistungsindikatoren in der Datenschicht erstellt, um die Anrufzeiten zu überwachen. Wenn Leistung schlecht ist, ist es wirklich schlecht für diesen einen Anruf. Aber wenn es gut ist, ist es wirklich gut. Ich konnte das Problem auf einigen verschiedenen Entwicklungsmaschinen reproduzieren, aber nicht auf unseren Entwicklungs- und Staging-Datenbankservern, die natürlich robustere Hardware haben. Im Allgemeinen wird das Problem durch einen Neustart der SQL Server-Dienste gelöst, aber nicht immer. Es gibt Indizes in der Tabelle für die Felder, die ich abfrage, aber es gibt mehr Indizes als ich möchte. Ich zögere jedoch, irgendwelche oder Spielzeug mit den Indizes aufgrund der Auswirkungen auf das Altsystem zu entfernen. Hat jemand schon einmal ein solches Problem erlebt oder haben Sie eine Empfehlung, Abhilfe zu schaffen?
CREATE TABLE [dbo].[product_performance_quarterly](
[performance_id] [int] IDENTITY(1,1) NOT FOR REPLICATION NOT NULL,
[product_id] [int] NULL,
[month] [int] NULL,
[year] [int] NULL,
[performance] [decimal](18, 6) NULL,
[gross_or_net] [char](15) NULL,
[vehicle_type] [char](30) NULL,
[quarterly_or_monthly] [char](1) NULL,
[stamp] [datetime] NULL CONSTRAINT [DF_product_performance_quarterly_stamp] DEFAULT (getdate()),
[eA_loaded] [nchar](10) NULL,
[vehicle_type_id] [int] NULL,
[yearmonth] [char](6) NULL,
[gross_or_net_id] [tinyint] NULL,
CONSTRAINT [PK_product_performance_quarterly_4_19_04] PRIMARY KEY CLUSTERED
(
[performance_id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 80) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[product_performance_quarterly] WITH NOCHECK ADD CONSTRAINT [FK_product_performance_quarterlyProduct_id] FOREIGN KEY([product_id])
REFERENCES [dbo].[products] ([product_id])
GO
ALTER TABLE [dbo].[product_performance_quarterly] CHECK CONSTRAINT [FK_product_performance_quarterlyProduct_id]
CREATE PROCEDURE [eA.Analytics.Calculations].[USP.GetCalculationData]
(
@PRODUCTID INT, --products.product_id
@BEGINYEAR INT, --year to begin retrieving performance data
@BEGINMONTH INT, --month to begin retrieving performance data
@ENDYEAR INT, --year to end retrieving performance data
@ENDMONTH INT, --month to end retrieving performance data
@QUARTERLYORMONTHLY VARCHAR(1), --do you want quarterly or monthly data?
@VEHICLETYPEID INT, --what product vehicle type are you looking for?
@GROSSORNETID INT --are your looking gross of fees data or net of fees data?
)
AS
BEGIN
SET NOCOUNT ON
DECLARE @STARTDATE VARCHAR(6),
@ENDDATE VARCHAR(6),
@vBEGINMONTH VARCHAR(2),
@vENDMONTH VARCHAR(2)
IF LEN(@BEGINMONTH) = 1
SET @vBEGINMONTH = '0' + CAST(@BEGINMONTH AS VARCHAR(1))
ELSE
SET @vBEGINMONTH = @BEGINMONTH
IF LEN(@ENDMONTH) = 1
SET @vENDMONTH = '0' + CAST(@ENDMONTH AS VARCHAR(1))
ELSE
SET @vENDMONTH = @ENDMONTH
SET @STARTDATE = CAST(@BEGINYEAR AS VARCHAR(4)) + @vBEGINMONTH
SET @ENDDATE = CAST(@ENDYEAR AS VARCHAR(4)) + @vENDMONTH
--because null values for gross_or_net_id and vehicle_type_id are represented in
--multiple ways (true null, empty string, or 0) in the PPQ table, need to account for all possible variations if
--a -1 is passed in from the .NET code, which represents an enumerated value that
--indicates that the value(s) should be true null.
IF @VEHICLETYPEID = '-1' AND @GROSSORNETID = '-1'
SELECT
PPQ.YEARMONTH, PPQ.PERFORMANCE
FROM PRODUCT_PERFORMANCE_QUARTERLY PPQ
WITH (NOLOCK)
WHERE
(PPQ.PRODUCT_ID = @PRODUCTID)
AND (PPQ.YEARMONTH BETWEEN @STARTDATE AND @ENDDATE)
AND (PPQ.QUARTERLY_OR_MONTHLY = @QUARTERLYORMONTHLY)
AND (PPQ.VEHICLE_TYPE_ID IS NULL OR PPQ.VEHICLE_TYPE_ID = '0' OR PPQ.VEHICLE_TYPE_ID = '')
AND (PPQ.GROSS_OR_NET_ID IS NULL OR PPQ.GROSS_OR_NET_ID = '0' OR PPQ.GROSS_OR_NET_ID = '')
ORDER BY PPQ.YEARMONTH ASC
IF @VEHICLETYPEID <> '-1' AND @GROSSORNETID <> '-1'
SELECT
PPQ.YEARMONTH, PPQ.PERFORMANCE
FROM PRODUCT_PERFORMANCE_QUARTERLY PPQ
WITH (NOLOCK)
WHERE
(PPQ.PRODUCT_ID = @PRODUCTID)
AND (PPQ.YEARMONTH BETWEEN @STARTDATE AND @ENDDATE)
AND (PPQ.QUARTERLY_OR_MONTHLY = @QUARTERLYORMONTHLY)
AND (PPQ.VEHICLE_TYPE_ID = @VEHICLETYPEID)
AND (PPQ.GROSS_OR_NET_ID = @GROSSORNETID)
ORDER BY PPQ.YEARMONTH ASC
IF @VEHICLETYPEID = '-1' AND @GROSSORNETID <> '-1'
SELECT
PPQ.YEARMONTH, PPQ.PERFORMANCE
FROM PRODUCT_PERFORMANCE_QUARTERLY PPQ
WITH (NOLOCK)
WHERE
(PPQ.PRODUCT_ID = @PRODUCTID)
AND (PPQ.YEARMONTH BETWEEN @STARTDATE AND @ENDDATE)
AND (PPQ.QUARTERLY_OR_MONTHLY = @QUARTERLYORMONTHLY)
AND (PPQ.VEHICLE_TYPE_ID IS NULL OR PPQ.VEHICLE_TYPE_ID = '0' OR PPQ.VEHICLE_TYPE_ID = '')
AND (PPQ.GROSS_OR_NET_ID = @GROSSORNETID)
ORDER BY PPQ.YEARMONTH ASC
IF @VEHICLETYPEID <> '-1' AND @GROSSORNETID = '-1'
SELECT
PPQ.YEARMONTH, PPQ.PERFORMANCE
FROM PRODUCT_PERFORMANCE_QUARTERLY PPQ
WITH (NOLOCK)
WHERE
(PPQ.PRODUCT_ID = @PRODUCTID)
AND (PPQ.YEARMONTH BETWEEN @STARTDATE AND @ENDDATE)
AND (PPQ.QUARTERLY_OR_MONTHLY = @QUARTERLYORMONTHLY)
AND (PPQ.VEHICLE_TYPE_ID = @VEHICLETYPEID)
AND (PPQ.GROSS_OR_NET_ID IS NULL OR PPQ.GROSS_OR_NET_ID = '0' OR PPQ.GROSS_OR_NET_ID = '')
ORDER BY PPQ.YEARMONTH ASC
END
Ich habe das auch gesehen, aber ich mache mir Sorgen, dass das Ausschalten das Problem einfach umkehrt (die schnellen Abfragen laufen jetzt langsam). Der einzige Grund, warum ich weiß, dass dies Auswirkungen auf Dinge hat, hängt mit Parameter-Sniffing zusammen, wo ein anderer Plan gewählt wird. –
Ich habe dieses Problem nicht festgestellt. Wenn ich es ausschalte, wird es gleichgesetzt mit dem, in dem SMS es ausführt. So habe ich das Problem gefunden. – Josef