Salah satu permintaan saya sedang berjalan dalam mode eksekusi serial setelah rilis dan saya perhatikan bahwa dua fungsi baru digunakan dalam tampilan yang direferensikan dalam LINQ ke SQL Query yang dihasilkan dari aplikasi. Jadi saya mengonversi fungsi-fungsi SCALAR ke fungsi TVF, tetapi masih query berjalan dalam mode serial.
Sebelumnya saya telah melakukan konversi Scalar ke TVF di beberapa pertanyaan lain dan itu memecahkan masalah eksekusi serial paksa.
Inilah fungsi skalar:
CREATE FUNCTION [dbo].[FindEventReviewDueDate]
(
@EventNumber VARCHAR(20),
@EventID VARCHAR(25),
@EventIDDate BIT
)
RETURNS DateTime
AS
BEGIN
DECLARE @CurrentEventStatus VARCHAR(20)
DECLARE @EventDateTime DateTime
DECLARE @ReviewDueDate DateTime
SELECT @CurrentEventStatus = (SELECT cis.EventStatus
FROM CurrentEventStatus cis
INNER JOIN Event1 r WITH (NOLOCK) ON (cis.Event1Id = r.Id)
WHERE (r.EventNumber = @EventNumber) AND r.EventID = @EventID)
SELECT @EventDateTime = (SELECT EventDateTime FROM Event1 r
WHERE (r.EventNumber = @EventNumber) AND r.EventID = @EventID)
IF @CurrentEventStatus IN ('0','6') AND EventIDDate = 1
BEGIN
SET @ReviewDueDate = DATEADD(DAY, 30, @EventDateTime)
WHILE @ReviewDueDate < getdate()
SET @ReviewDueDate = DATEADD(DAY, 30, @ReviewDueDate)
DECLARE @EventDateJournalDate DateTime
SELECT @EventDateJournalDate = (SELECT TOP 1 ij.Date
FROM EventPage_EventJournal ij
INNER JOIN EventJournalPages p ON ij.PageId = p.Id
INNER JOIN Journal f ON p.FormId = f.Id
INNER JOIN Event1 r WITH (NOLOCK) ON (f.Event1Id = r.Id)
WHERE (r.EventNumber = @EventNumber AND r.EventID = @EventID) AND ij.ReviewType = 'Supervisor Monthly Review' ORDER BY ij.Date DESC)
IF(DATEADD(DAY, 30, @EventDateTime) < getdate() AND
(@EventDateJournalDate is null OR DATEADD(DAY, 30, @EventDateJournalDate) < getdate()) AND
DATEADD(DAY, 14, @ReviewDueDate) > DATEADD(DAY, 30, getdate()))
SET @ReviewDueDate = DATEADD(DAY, -30, @ReviewDueDate)
ELSE IF((@EventDateJournalDate is not null ) AND (DATEADD(DAY, 30, @EventDateJournalDate) >= @ReviewDueDate))
SET @ReviewDueDate = DATEADD(DAY, 30, @ReviewDueDate)
END
RETURN @ReviewDueDate
END
Berikut adalah fungsi TVF yang dikonversi.
CREATE FUNCTION [dbo].[FindEventReviewDueDate_test]
(
@EventNumber VARCHAR(20),
@EventID VARCHAR(25),
@EventIDDate BIT
)
RETURNS @FunctionResultTableVairable TABLE (
CurrentEventStatus varchar(20),
Event1DateTime DateTime,
ReviewDueDate DateTime
)
AS
BEGIN
DECLARE @CurrentEventStatus VARCHAR(20)
DECLARE @EventDateTime DateTime
DECLARE @ReviewDueDate DateTime
SELECT @CurrentEventStatus = (SELECT cis.EventStatus
FROM CurrentEventStatus cis
INNER JOIN Event1 r WITH (NOLOCK) ON (cis.Event1Id = r.Id)
WHERE (r.EventNumber = @EventNumber) AND r.EventID = @EventID)
SELECT @EventDateTime = (SELECT EventDateTime FROM Event1 r
WHERE (r.EventNumber = @EventNumber) AND r.EventID = @EventID)
IF @CurrentEventStatus IN ('0','6') AND EventIDDate = 1
BEGIN
SET @ReviewDueDate = DATEADD(DAY, 30, @EventDateTime)
WHILE @ReviewDueDate < getdate()
SET @ReviewDueDate = DATEADD(DAY, 30, @ReviewDueDate)
DECLARE @EventDateJournalDate DateTime
SELECT @EventDateJournalDate = (SELECT TOP 1 ij.Date
FROM EventPage_EventJournal ij
INNER JOIN EventJournalPages p ON ij.PageId = p.Id
INNER JOIN Journal f ON p.FormId = f.Id
INNER JOIN Event1 r WITH (NOLOCK) ON (f.Event1Id = r.Id)
WHERE (r.EventNumber = @EventNumber AND r.EventID = @EventID) AND ij.ReviewType = 'Supervisor Monthly Review' ORDER BY ij.Date DESC)
IF(DATEADD(DAY, 30, @EventDateTime) < getdate() AND
(@EventDateJournalDate is null OR DATEADD(DAY, 30, @EventDateJournalDate) < getdate()) AND
DATEADD(DAY, 14, @ReviewDueDate) > DATEADD(DAY, 30, getdate()))
SET @ReviewDueDate = DATEADD(DAY, -30, @ReviewDueDate)
ELSE IF((@EventDateJournalDate is not null ) AND (DATEADD(DAY, 30, @EventDateJournalDate) >= @ReviewDueDate))
SET @ReviewDueDate = DATEADD(DAY, 30, @ReviewDueDate)
insert into @FunctionResultTableVairable
select @CurrentEventStatus,@EventDateTime,@ReviewDueDate
END
return;
END
GO
Apakah ada yang salah dengan penerapan fungsi TVF yang mencegah kueri berjalan dalam mode paralel.
Saya menggunakan fungsi TVF dalam kueri seperti di bawah ini;
select ReviewDueDate from dbo.FunctionResultTableVairable('a','b','c')
Permintaan aktual saya yang menggunakan tampilan cukup rumit dan jika saya mengomentari bagian fungsi dalam tampilan dan mengeksekusi, permintaan berjalan secara paralel. Jadi itu adalah fungsi yang memaksa permintaan untuk berjalan secara paralel.
Permintaan saya yang sebenarnya adalah dalam format di bawah ini.
select
dv.column1,
dv.column2,
---------
---------
--------
(select ReviewDueDate from dbo.FunctionResultTableVairable('a','b','c')) AS 'Columnx'
from
DemoView dv
Where
condition1
conditon 2
Bantuan apa pun dihargai.
sumber
Jawaban:
Iya. Sesuatu seperti di bawah ini akan melakukannya.
Itu masih lumayan dan jika dijalankan berkorelasi kemungkinan akan sangat tidak efisien. Seperti yang ditunjukkan Aaron dalam komentar Anda menyebutnya dengan nilai konstan, jadi semoga saja rencana kueri mencerminkan ini dan hanya menjalankannya sekali.
sumber
Forrest sebagian besar benar, tetapi detail yang lebih halus adalah:
SQL Server tidak dapat memparalelkan modifikasi ke variabel tabel, yang digunakan fungsi Anda.
Sebelum Eksekusi Interleaved SQL Server 2017 , estimasi baris dari Multi-Statement Table Valued Functions sangat rendah.
Salah satu efek samping dari ini adalah bahwa rencana dibiayai sangat buruk pada kelas bawah, dan seringkali tidak akan melanggar ambang biaya untuk paralelisme.
sumber
SQL Server tidak dapat memparalelkan TVFs multi-pernyataan, yang merupakan milik Anda. Hanya TVFs sebaris yang dapat diparalelkan.
sumber