เปลี่ยนค่าเริ่มต้นทั้งระบบสำหรับ maxrecursion


12

ฉันจะเปลี่ยนค่าเริ่มต้นของทั้งระบบได้MAXRECURSIONอย่างไร

โดยค่าเริ่มต้นคือ 100 แต่ฉันต้องเพิ่มเป็น 1,000 เช่น

ฉันไม่สามารถใช้คำแนะนำการสืบค้นได้เนื่องจากฉันกำลังใช้โปรแกรมที่ใช้การสืบค้นของฉันและดำเนินการให้ฉันและฉันไม่สามารถแก้ไขข้อ จำกัด นี้ได้

อย่างไรก็ตามฉันมีสิทธิ์ของผู้ดูแลระบบในอินสแตนซ์ของเซิร์ฟเวอร์ ฉันแหย่ไปรอบ ๆ ในแง่มุมของเซิร์ฟเวอร์ แต่ฉันไม่เห็นสิ่งใดที่เกี่ยวข้องกับตัวเลือกแบบสอบถามหรือการเรียกซ้ำ ผมถือว่ามีมีจะเป็นที่ใดที่หนึ่งสถานที่ที่ฉันสามารถอัปเดตเริ่มต้นทั้งระบบ

ความคิดใด ๆ


3
ฉันแค่ต้องการตรวจสอบว่าคุณเข้าใจว่าขีด จำกัด ของ 100 เป็นเพียงการดูและฟังก์ชั่นเท่านั้นและคุณสามารถใช้ขั้นตอนการจัดเก็บและแทนที่ภายในเครื่องได้หรือไม่ จำเป็นต้องใช้ฟังก์ชั่นพิเศษหรือไม่? เนื่องจากการเรียกซ้ำไม่มีประสิทธิภาพพอสมควรฉันจึงขอแนะนำให้เดินลำดับชั้นเพียงครั้งเดียวและเก็บผลลัพธ์ไว้ในตาราง จากนั้นคุณสามารถสร้างฟังก์ชันที่อ้างถึงตารางนั้น คุณคิดอย่างไร?
wBob

คำตอบ:


10

หากคำค้นหาของคุณมีรูปร่างที่เหมือนกันคุณอาจจะสามารถเพิ่มคำแนะนำสูงสุดที่จำเป็นโดยใช้คำแนะนำแผนอย่างน้อยหนึ่งรายการ

อาจมีความสามารถพิเศษในการทำให้ถูกต้อง หากคุณเพิ่มรายละเอียดการสืบค้นเฉพาะลงในคำถามของคุณเราอาจช่วยคุณได้ โดยทั่วไปแล้วคุณจะติดตาม SQL โดยการกดปุ่มเซิร์ฟเวอร์หรือรับแบบฟอร์มที่กำหนดพารามิเตอร์โดยใช้โพรซีเดอร์ในตัวsys.sp_get_query_templateแล้วสร้างคำแนะนำแผน TEMPLATE และ / หรือ OBJECT / SQL

ดูเอกสารประกอบสำหรับข้อมูลเพิ่มเติม:

คำแนะนำแผนจะต้องมีการตรวจสอบความถูกต้องทุกครั้งที่มีการเปลี่ยนแปลงรหัสแอปพลิเคชันและเมื่อมีการติดตั้งหรืออัพเกรด SQL Server นี่ควรเป็นส่วนหนึ่งของรอบการทดสอบปกติของคุณ

โปรดทราบว่าการตรวจสอบความถูกต้องของคู่มือแผนโดยใช้sys.fn_validate_plan_guideอาจรายงานความล้มเหลวอย่างไม่ถูกต้องหากคำแนะนำที่อ้างอิงถึงตารางชั่วคราว ดูคำถามนี้:

การตรวจสอบความถูกต้องของคู่มือแผนด้วย fn_validate_plan_guide จะให้ผลบวกเป็นเท็จ

แผนคู่มือที่ประสบความสำเร็จและแผนไม่สำเร็จคู่มือ Profiler และกิจกรรมขยายชั้นเรียนนอกจากนี้ยังสามารถนำมาใช้ในการตรวจสอบการใช้งานคู่มือแผน

เชื่อมต่อเกษียณอายุราชการก่อนที่จะเสนอแนะการปรับปรุงสินค้าอนุญาตให้ MAXRECURSION ค่าขีด จำกัด อื่น ๆ กว่า 100 มุมมองและ UDF ของสตีฟ Kassถูกนำมาใช้ ถ้าคุณอยากจะใช้มันขึ้นกับไมโครซอฟท์ในขณะนี้ดูตัวเลือกที่SQL Server ช่วยเหลือและความคิดเห็น


สิ่งนี้น่าผิดหวังและไม่ตอบคำถามแทนการฝังเราไว้ในช่องเอกสาร EF Core (ORM ทั่วไป) สร้างคิวรีให้คุณแม้ว่าคุณจะให้คำสั่ง SQL แบบ raw มันจะตัดคำนั้นในรายการหลักทุกคนที่ใช้ EF Core มีปัญหานี้ โซลูชันของคุณคือ "วางแผนข้อความค้นหาของคุณ"
สงคราม

@War มันเป็นคำตอบที่ดีที่สุดที่ฉันสามารถให้กับคำถามนี้โดยมีรายละเอียดที่ให้ไว้ วิธีเดียวที่ฉันรู้ในการเพิ่มคำแนะนำการเรียกซ้ำสูงสุดคือผ่านทาง SQL Server ที่เรียกว่า Plan Guide ซึ่งไม่มีส่วนเกี่ยวข้องกับ "การวางแผนการสืบค้นของคุณ" หากคุณมีคำถามเฉพาะของคุณเองโปรดขอให้มันแยกกันด้วยตัวอย่างเช่นสามารถทำซ้ำได้น้อยที่สุด
Paul White 9

9

หากคุณจำเป็นต้องใช้ฟังก์ชั่นอย่างแน่นอน (ข้อ จำกัด ของเครื่องมือ ETL ของคุณตามที่คุณพูดถึง) คุณสามารถระบุOPTIONเป็นส่วนหนึ่งของฟังก์ชั่นที่มีมูลค่าเป็นตารางหลายคำสั่งเช่นสิ่งต่อไปนี้:

CREATE FUNCTION dbo.udf_MyFunction ( @StartID INT ) 
RETURNS @tv TABLE
(
id INT
)
AS
BEGIN

    WITH Episodes( xlevel, PersonID, EventID, EpisodeID, StartDT, EndDT ) AS (
    -- Anchor case - the first EventID for each person.
    SELECT 1 AS xlevel, PersonID, EventID, @StartID, StartDT, EndDT 
    FROM dbo.EventTable
    WHERE EventID = @StartID

    UNION ALL

    SELECT xlevel + 1, et.PersonID, et.EventID, c.EventID + 1, et.StartDT, et.EndDT
    FROM Episodes c
        INNER JOIN dbo.EventTable et ON c.PersonID = et.PersonID
            AND et.EventID = c.EventID + 1
    --WHERE c.EventID <= (@StartID + 99)
    )
    INSERT INTO @tv
    SELECT PersonID
    FROM Episodes
    OPTION ( MAXRECURSION 1000 )

    RETURN

END
GO

นอกจากนี้ยังใช้งานได้กับฉันเมื่อมีการห่อหุ้มมุมมองตามที่คุณแนะนำเครื่องมือ ETL ของคุณ ไม่มีวิธีที่จะแก้ไขทั้งระบบนี้ แต่เนื่องจากการเรียกซ้ำอาจไม่มีประสิทธิภาพนี่อาจเป็นสิ่งที่ดี คุณไม่สามารถระบุคำใบ้แบบสอบถาม (โดยใช้OPTION) ภายในเนื้อความของฟังก์ชั่นค่าตารางแบบอินไลน์เช่นในตัวอย่างของคุณ

พิจารณาการเปลี่ยนแปลงกระบวนการของคุณเพื่อดำเนินการลำดับชั้นเพียงครั้งเดียวเมื่อคุณได้รับตอนของคุณและเก็บผลลัพธ์ในตารางสัมพันธ์ คุณสามารถใช้ proc ที่เก็บไว้เพื่อทำเช่นนี้จะไม่พบข้อ จำกัด นี้

ฉันคิดว่าอาจมีข้อผิดพลาดในรหัสของคุณด้วย: หาก CTE ของคุณเข้าร่วม personId และเรียกคืนใน eventId, eventId 101 จะแสดงสองครั้งที่ฉันคิดว่าเป็นสำเนา อาจเป็นไปได้ว่าฉันตีความรหัสของคุณผิดโปรดแจ้งให้เราทราบว่าคุณคิดอย่างไร

HTH


สิ่งนี้ไม่ทำงานเนื่องจากต้องใช้พารามิเตอร์ "OPTIONS" ที่ระดับคำสั่งและคำสั่งที่เป็นปัญหาคือการเรียกใช้ฟังก์ชันซึ่งจะส่งกลับข้อยกเว้น
สงคราม

0

ฉันได้แรงบันดาลใจจากหัวข้อนี้

นี่คือสิ่งที่ฉันได้ทำเพื่อแก้ไขปัญหา

CREATE FUNCTION MySchema.udf_MyFunction(@StartID INT) 
RETURNS TABLE 
AS RETURN
WITH
Episodes(PersonID, EventID, EpisodeID, StartDT, EndDT) AS (
  -- Anchor case - the first EventID for each person.
  SELECT PersonID, EventID, @StartID, StartDT, EndDT 
  FROM MySchema.EventTable
  WHERE EventID = @StartID
UNION ALL
  SELECT
    ...
  WHERE
    EventID <= (@StartID + 99)
)
SELECT * FROM Episodes

จากนั้นฉันจะเรียกใช้ฟังก์ชันนี้เช่นนี้:

WITH
Episodes AS (
  SELECT * FROM MySchema.udf_MyFunction(1)
UNION ALL
  SELECT * FROM MySchema.udf_MyFunction(101)
UNION ALL
  SELECT * FROM MySchema.udf_MyFunction(201)
-- ...
UNION ALL
  SELECT * FROM MySchema.udf_MyFunction(901)
)
SELECT * FROM Episodes

ด้วยวิธีนี้ไม่มีตรรกะ CTE ของฉันซ้ำอีกและฉันไม่ต้องจ่ายอะไรเพิ่มเติมในแง่ของประสิทธิภาพ มันเป็นเรื่องน่ารำคาญที่ต้องทำแบบนี้ แต่ฉันสามารถอยู่กับมันได้


3
ฉันไม่เห็นว่าวิธีนี้แก้ปัญหาการเรียกซ้ำได้อย่างไร การเรียกใช้ฟังก์ชันไม่เกิดซ้ำ
ypercubeᵀᴹ

@ ypercubeᵀᴹ - บิตแบบเรียกซ้ำของ CTE ไปที่จุดไข่ปลาของฉัน - ตรรกะแบบเรียกซ้ำโดยเฉพาะของฉันไม่เกี่ยวข้องกับปัญหา แต่คุณสามารถสมมติได้ว่า CTE นั้นเป็นแบบเรียกซ้ำ ส่วนwhereคำสั่งหลังจากจุดไข่ปลาป้องกันไม่ให้เกิดการเรียกซ้ำหลายครั้งมากเกินไปโดยใช้พารามิเตอร์ฟังก์ชันเป็นข้อ จำกัด ฉันเดาว่าควรจะมีคำสั่งหลังจากนิยาม CTE ฉันจะเพิ่มที่
carl.anderson

3
ฉันเข้าใจดีว่า CTE ซ้ำซาก ปัญหาคือว่าภาวนา (ฟังก์ชั่นการโทร) จะไม่เรียกซ้ำ ตัวอย่างเช่นคุณเรียกใช้ฟังก์ชันที่มีจุดเริ่มต้น (แถว) ด้วยEventID=1(และ 101,201, ... 901) แต่แบบสอบถามดั้งเดิม (หากเรียกใช้ด้วย MAXRECURSION = 100000000) อาจไม่เคยเยี่ยมชมแถวด้วยEventID=101(และ 201, .. , 901) ดังนั้นข้อความค้นหาสองรายการ (ต้นฉบับและโซลูชันของคุณ) อาจให้ผลลัพธ์ที่แตกต่างกัน (ไม่มีแถวที่ 101 ในอันแรกใช่ในข้อ 2)! หรืออาจไปที่ 101 แต่ก่อนหน้าขั้นตอนที่ 100 ดังนั้นโซลูชันของคุณจะรวมแถวสองครั้งในผลลัพธ์ (ต่างกันอีกครั้ง)
ypercubeᵀᴹ

2
เว้นแต่ว่าข้อมูลจะเชื่อมต่อค่า EventID ลำดับตามลำดับ (1,2,, 3 ... , 99,100,101, .. ) ในกรณีนี้คุณไม่จำเป็นต้องมี CTE แบบเรียกซ้ำทั้งหมด
ypercubeᵀᴹ

วิธีนี้แก้ปัญหาความลึกที่ไม่รู้จักสำหรับบางอย่างเช่น ... รับต้นไม้จากเส้นทาง DMS ที่กำหนดเป็น rowset ได้อย่างไร
สงคราม
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.