Запрос с параметрами и без параметров -> совершенно другое время выполнения - PullRequest
3 голосов
/ 10 апреля 2019

У меня есть проблема, которую я не понимаю.

У меня есть запрос с двумя условиями. Этот запрос был очень медленным, поэтому я создал индекс. после этого у меня какое-то странное поведение. Если я запускаю запрос напрямую с ... WHERE xxx=1234 результат будет доставлен через 4 мс когда я использую такие параметры, как

DECLARE @P1 bigint
SET @P1=1234

...WHERE xxx=@P1 

результат будет доставлен в течение 80k мс

Я нашел некоторую информацию о сниффинге параметров - и я его деактивировал - то же самое поведение. Я деактивировал его с помощью

ALTER DATABASE SCOPED CONFIGURATION SET PARAMETER_SNIFFING = OFF;

Когда я запускаю запрос с OPTION (OPTIMIZE FOR (@P1 = 1234)) результат снова будет доставлен через 4 мс.

Моя проблема: у меня нет возможности использовать OPTIMIZE FOR, потому что SQL-оператор, потому что этот запрос запрашивается программой.

Не могли бы вы, ребята, сказать мне, как я могу сказать SQL-серверу использовать план запроса, как он использует без параметров?

Это CREATE TABLE для таблицы:

CREATE TABLE [dbo].[CRM_RO](
    [ID] [bigint] NOT NULL,
    [ID_FI] [bigint] NOT NULL,
    [ID_PE] [bigint] NOT NULL,
    [ID_GENERIC] [bigint] NOT NULL,
    [DateiKurzk] [nchar](4) NOT NULL,
    [RelPosNr] [int] NOT NULL,
    [Partnerrolle] [int] NOT NULL,
    [KopfExtKey] [nvarchar](20) NULL,
    [PosExtKey] [nvarchar](20) NULL,
    [Dokument1] [nvarchar](20) NULL,
    [Dokument2] [nvarchar](20) NULL,
    [SAPAbglStat] [tinyint] NOT NULL,
    [SAPAbglDatum_DT] [bigint] NOT NULL,
    [SAPAbglModus] [tinyint] NOT NULL,
    [FreiK1] [int] NOT NULL,
    [FreiK2] [int] NOT NULL,
    [FreiK3] [int] NOT NULL,
    [FreiK4] [int] NOT NULL,
    [FreiK5] [int] NOT NULL,
    [FreiC1] [nvarchar](40) NULL,
    [FreiC2] [nvarchar](40) NULL,
    [FreiC3] [nvarchar](40) NULL,
    [FreiC4] [nvarchar](40) NULL,
    [FreiC5] [nvarchar](40) NULL,
    [FreiN1] [int] NOT NULL,
    [FreiN2] [int] NOT NULL,
    [FreiN3] [int] NOT NULL,
    [FreiN4] [int] NOT NULL,
    [FreiN5] [int] NOT NULL,
    [FreiD1] [int] NOT NULL,
    [FreiD2] [int] NOT NULL,
    [FreiD3] [int] NOT NULL,
    [FreiD4] [int] NOT NULL,
    [FreiD5] [int] NOT NULL,
    [FreiL1] [bit] NOT NULL,
    [FreiL2] [bit] NOT NULL,
    [FreiL3] [bit] NOT NULL,
    [FreiL4] [bit] NOT NULL,
    [FreiL5] [bit] NOT NULL,
    [FreiDez1] [float] NOT NULL,
    [FreiDez2] [float] NOT NULL,
    [FreiDez3] [float] NOT NULL,
    [FreiDez4] [float] NOT NULL,
    [FreiDez5] [float] NOT NULL,
    [Neu] [bigint] NOT NULL,
    [Upd] [bigint] NOT NULL,
    [UpdL] [bigint] NOT NULL,
    [LosKZ] [bit] NOT NULL,
    [AstNr] [int] NOT NULL,
    [KomKz] [bit] NOT NULL,
    [RKZ] [binary](30) NOT NULL,
    [Inaktiv] [bit] NOT NULL,
    [DatumVon] [int] NOT NULL,
    [DatumBis] [int] NOT NULL,
    [UPD_FIELD] [varbinary](334) NULL,
    [MNO] [int] NOT NULL,
    [F7000] [int] NOT NULL,
    [F7002] [int] NOT NULL,
    [F7004] [nvarchar](35) NULL,
    [F7005] [nvarchar](35) NULL,
    [F7006] [nvarchar](35) NULL,
    [F7007] [nvarchar](35) NULL,
    [F7008] [nvarchar](35) NULL,
    [F7009] [int] NOT NULL,
    [F7010] [nvarchar](35) NULL,
PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[CRM_RO] ADD  DEFAULT ((0)) FOR [ID]
GO

ALTER TABLE [dbo].[CRM_RO] ADD  DEFAULT ((0)) FOR [ID_FI]
GO

ALTER TABLE [dbo].[CRM_RO] ADD  DEFAULT ((0)) FOR [ID_PE]
GO

ALTER TABLE [dbo].[CRM_RO] ADD  DEFAULT ((0)) FOR [ID_GENERIC]
GO

ALTER TABLE [dbo].[CRM_RO] ADD  DEFAULT ('') FOR [DateiKurzk]
GO

ALTER TABLE [dbo].[CRM_RO] ADD  DEFAULT ((0)) FOR [RelPosNr]
GO

ALTER TABLE [dbo].[CRM_RO] ADD  DEFAULT ((0)) FOR [Partnerrolle]
GO

ALTER TABLE [dbo].[CRM_RO] ADD  DEFAULT ((0)) FOR [SAPAbglStat]
GO

ALTER TABLE [dbo].[CRM_RO] ADD  DEFAULT ((0)) FOR [SAPAbglDatum_DT]
GO

ALTER TABLE [dbo].[CRM_RO] ADD  DEFAULT ((0)) FOR [SAPAbglModus]
GO

ALTER TABLE [dbo].[CRM_RO] ADD  DEFAULT ((0)) FOR [FreiK1]
GO

ALTER TABLE [dbo].[CRM_RO] ADD  DEFAULT ((0)) FOR [FreiK2]
GO

ALTER TABLE [dbo].[CRM_RO] ADD  DEFAULT ((0)) FOR [FreiK3]
GO

ALTER TABLE [dbo].[CRM_RO] ADD  DEFAULT ((0)) FOR [FreiK4]
GO

ALTER TABLE [dbo].[CRM_RO] ADD  DEFAULT ((0)) FOR [FreiK5]
GO

ALTER TABLE [dbo].[CRM_RO] ADD  DEFAULT ((0)) FOR [FreiN1]
GO

ALTER TABLE [dbo].[CRM_RO] ADD  DEFAULT ((0)) FOR [FreiN2]
GO

ALTER TABLE [dbo].[CRM_RO] ADD  DEFAULT ((0)) FOR [FreiN3]
GO

ALTER TABLE [dbo].[CRM_RO] ADD  DEFAULT ((0)) FOR [FreiN4]
GO

ALTER TABLE [dbo].[CRM_RO] ADD  DEFAULT ((0)) FOR [FreiN5]
GO

ALTER TABLE [dbo].[CRM_RO] ADD  DEFAULT ((0)) FOR [FreiD1]
GO

ALTER TABLE [dbo].[CRM_RO] ADD  DEFAULT ((0)) FOR [FreiD2]
GO

ALTER TABLE [dbo].[CRM_RO] ADD  DEFAULT ((0)) FOR [FreiD3]
GO

ALTER TABLE [dbo].[CRM_RO] ADD  DEFAULT ((0)) FOR [FreiD4]
GO

ALTER TABLE [dbo].[CRM_RO] ADD  DEFAULT ((0)) FOR [FreiD5]
GO

ALTER TABLE [dbo].[CRM_RO] ADD  DEFAULT ((0)) FOR [FreiL1]
GO

ALTER TABLE [dbo].[CRM_RO] ADD  DEFAULT ((0)) FOR [FreiL2]
GO

ALTER TABLE [dbo].[CRM_RO] ADD  DEFAULT ((0)) FOR [FreiL3]
GO

ALTER TABLE [dbo].[CRM_RO] ADD  DEFAULT ((0)) FOR [FreiL4]
GO

ALTER TABLE [dbo].[CRM_RO] ADD  DEFAULT ((0)) FOR [FreiL5]
GO

ALTER TABLE [dbo].[CRM_RO] ADD  DEFAULT ((0)) FOR [FreiDez1]
GO

ALTER TABLE [dbo].[CRM_RO] ADD  DEFAULT ((0)) FOR [FreiDez2]
GO

ALTER TABLE [dbo].[CRM_RO] ADD  DEFAULT ((0)) FOR [FreiDez3]
GO

ALTER TABLE [dbo].[CRM_RO] ADD  DEFAULT ((0)) FOR [FreiDez4]
GO

ALTER TABLE [dbo].[CRM_RO] ADD  DEFAULT ((0)) FOR [FreiDez5]
GO

ALTER TABLE [dbo].[CRM_RO] ADD  DEFAULT ((0)) FOR [Neu]
GO

ALTER TABLE [dbo].[CRM_RO] ADD  DEFAULT ((0)) FOR [Upd]
GO

ALTER TABLE [dbo].[CRM_RO] ADD  DEFAULT ((0)) FOR [UpdL]
GO

ALTER TABLE [dbo].[CRM_RO] ADD  DEFAULT ((0)) FOR [LosKZ]
GO

ALTER TABLE [dbo].[CRM_RO] ADD  DEFAULT ((0)) FOR [AstNr]
GO

ALTER TABLE [dbo].[CRM_RO] ADD  DEFAULT ((0)) FOR [KomKz]
GO

ALTER TABLE [dbo].[CRM_RO] ADD  DEFAULT (0x) FOR [RKZ]
GO

ALTER TABLE [dbo].[CRM_RO] ADD  DEFAULT ((0)) FOR [Inaktiv]
GO

ALTER TABLE [dbo].[CRM_RO] ADD  DEFAULT ((0)) FOR [DatumVon]
GO

ALTER TABLE [dbo].[CRM_RO] ADD  DEFAULT ((0)) FOR [DatumBis]
GO

ALTER TABLE [dbo].[CRM_RO] ADD  DEFAULT ((0)) FOR [MNO]
GO

ALTER TABLE [dbo].[CRM_RO] ADD  DEFAULT ((0)) FOR [F7000]
GO

ALTER TABLE [dbo].[CRM_RO] ADD  DEFAULT ((0)) FOR [F7002]
GO

ALTER TABLE [dbo].[CRM_RO] ADD  DEFAULT ((0)) FOR [F7009]
GO

Это код CREATE INDEX. Пожалуйста, запутайтесь в названии "отсутствующий индекс". Это только потому, что я использовал синтаксис. Я сделал Индекс от ЗАКАЗА ПО:

CREATE INDEX [QS_missing_index_583420_583419_CRM_RO] ON [CRM].[dbo].[CRM_RO] (ID_FI,ID_PE,DateiKurzk,ID_GENERIC,RelPosNr,Partnerrolle)

1 Ответ

0 голосов
/ 20 апреля 2019

Это одна из причин, по которой мы используем хранимые процедуры, а не реальные запросы в приложениях.Если запрос должен быть настроен, как это делается, гораздо проще внести изменения в хранимую процедуру, чем открывать приложение.

С учетом вышесказанного взломайте приложение и обменяйте запрос нахранимая процедура - действительно лучший ответ.

Единственный другой возможный способ настройки этого запроса - через хранилище запросов.Взгляните на эту страницу: https://blogs.technet.microsoft.com/dataplatform/2017/01/31/query-store-how-it-works-how-to-use-it/

В частности, «1) Можно сравнивать планы, особенно полезно в случае перехвата параметров» & «2) Также возможно форсировать планы»..

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...