Maxrecursion için sistem genel varsayılanını değiştirme


12

Sistem genelinde varsayılan değerini nasıl değiştirebilirim MAXRECURSION?

Varsayılan olarak 100'dür, ancak 1000'e yükseltmem gerekiyor.

Sorgumu alıp benim için yürüten bir program kullandığım ve ne yazık ki bu sınırlamayı alamıyorum çünkü sorgu ipuçlarını kullanamıyorum.

Ancak, sunucu örneği üzerinde yönetici haklarına sahibim. Ben sunucu yönleri etrafında dürttü, ama orada sorgu seçenekleri veya özyineleme ile ilgili bir şey görmüyorum. Orada varsayalım vardır ben sistem çapında varsayılan güncelleyebilirsiniz bir yer yerde olması.

Herhangi bir fikir?


3
Sadece 100 limitinin sadece görünümler ve fonksiyonlar üzerinde olduğunu ve saklı bir prosedürü kullanabileceğinizi ve orada yerel olarak geçersiz kılabileceğinizi anladığınızı kontrol etmek istedim? Bir işlevi kullanmak için özel bir ihtiyaç var mı? Özyineleme oldukça verimsiz olduğundan, hiyerarşiyi yalnızca bir kez yürümeyi ve çıktıyı bir tabloda depolamayı da öneririm. Daha sonra bu tabloya gönderme yapan bir işlev oluşturabilirsiniz. Ne düşünüyorsun?
wBob

Yanıtlar:


10

Sorgularınız ortak bir şekle sahipse, bir veya daha fazla plan kılavuzu kullanarak gerekli maksrecursion ipucunu ekleyebilirsiniz.

Onları düzeltmek için bir ustalık olabilir. Sorunuza belirli sorgu ayrıntıları eklerseniz, bunu sizin için çözebiliriz. Genellikle, sunucuya gerçekten isabet eden SQL'i izler veya yerleşik sys.sp_get_query_template yordamını kullanarak parametreli bir form alırsınız ve sonra bir TEMPLATE ve / veya OBJECT / SQL plan kılavuzu oluşturabilirsiniz.

Daha fazla bilgi için belgelere bakın:

Uygulama kodu her değiştiğinde ve SQL Server yamalandığında veya yükseltildiğinde plan kılavuzlarının yeniden doğrulanması gerekir. Bu sadece normal test döngünüzün bir parçası olmalıdır.

Kılavuzlu deyimin geçici bir tabloya başvurması durumunda sys.fn_validate_plan_guide kullanarak plan kılavuzu doğrulamasının yanlış bir hata bildirebileceğini unutmayın. Bu soruya bakın:

Fn_validate_plan_guide ile plan doğrulaması yanlış pozitifler veriyor

Plan Kılavuzu Başarılı ve Plan Kılavuzu başarısız Profiler ve Genişletilmiş Olaylar dersleri de planı kılavuz uygulamaları izlemek için kullanılabilir.

Ürün iyileştirme önerisi bağlanmadan önce kullanımdan kaldırıldı Görünümler için 100'den fazla MAXRECURSION sınır değerine izin ver ve Steve Kass tarafından UDF'ler uygulandı. Şimdi Microsoft'u kullanmak istiyorsanız, SQL Server yardım ve geri bildirimindeki seçeneklere bakın .


Bu sinir bozucu ve bunun yerine bizi bir tavşan deliğine gömmek sorusuna cevap vermiyor. EF Core (tipik bir ORM), bir Ebeveyn seçiminde EF Core kullanan herkesin bu soruna sahip olduğunu saran ham bir SQL ifadesi verseniz bile sizin için sorgular oluşturur. Çözümünüz "sorgularınızı planlayın".
Savaş

@War Bu özel soruya verilen ayrıntılarla verebileceğim en iyi cevap. Bir max özyineleme ipucu eklemek için bildiğim tek yolu , Plan sorgu adlı "sorgularınızı planlama" ile ilgisi olmayan bir SQL Server şey üzerinden olduğunu. Size özel bir sorunuz varsa, lütfen minimal tekrarlanabilir bir örnekle ayrı olarak sorun .
Paul White 9

9

Kesinlikle bir işlev kullanmak zorundaysanız (ima ettiğiniz gibi ETL aracınızın bir sınırlaması), OPTIONçok ifadeli tablo değerli bir işlevin parçası olarak belirtebilirsiniz , örneğin, böyle bir şey:

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

Bu, ETL araçlarınızın önerdiği gibi bir görünümde sarıldığında da benim için çalıştı. Bu sistemi tümüyle değiştirmenin bir yolu yoktur, ancak özyineleme verimsiz olabileceğinden, bu muhtemelen iyi bir şeydir. OPTIONÖrneğin, satır içi tablo değerli bir işlev gövdesi içinde bir sorgu ipucu (kullanarak ) belirtemezsiniz .

Bölümlerinizi aldığınızda ve çıktıyı ilişkisel bir tabloda sakladığınızda hiyerarşiyi yürütebilmek için işleminizi değiştirmeyi düşünün. Bunu yapmak için depolanmış bir proc kullanabilirsiniz, bu nedenle bu sınırlamaya girmezsiniz.

Ayrıca kodunuzda bir hata olabileceğini düşünüyorum: CTE'niz personId'e katılırsa ve eventId'deki recurses'larda, eventId 101, iki kez, bir kopya olarak düşünüyorum. Muhtemelen kodunuzu yanlış yorumladım, ne düşündüğünüzü bana bildirin.

HTH


"OPTIONS" parametresinin ifade düzeyinde uygulanması gerektiğinden ve söz konusu ifade işleve çağrı olduğundan bu çalışmaz, bu bir istisna döndürür.
Savaş

0

Bu konudan ilham aldım .

İşte sorunu çözmek için yaptığım şey.

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

Sonra bu işlevi şöyle çağırır:

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

Bu şekilde, CTE mantığımın hiçbiri tekrarlanmamalı ve performans açısından fazladan bir şey ödemem. Bu şekilde yapılması bir sıkıntı, ama onunla yaşayabilirim.


3
Bunun bir özyineleme sorununu nasıl çözdüğünü görmüyorum. İşlevin çağrılması özyinelemeli değildir.
ypercubeᵀᴹ

@ ypercubeᵀᴹ - CTE'nin özyinelemeli biti benim üç noktamın olduğu yere gider - özel özyinelemeli mantığım sorunla gerçekten ilgili değildir, ancak CTE'nin aslında özyinelemeli olduğunu varsayabilirsiniz. Üç wherenoktadan sonraki yan tümce, function parametresini bir kısıtlama olarak kullanarak çok fazla yinelemenin olmasını engeller. Yine de CTE tanımından sonra bir açıklama olmalı . Bunu ekleyeceğim.
carl.anderson

3
CTE'nin özyinelemeli olduğunu çok iyi anlıyorum. Sorun çağırma (işlev çağrıları) özyinelemeli olmasıdır . Örneğin, EventID=1(ve 101,201, ... 901) ile başlangıç ​​noktalarına (satırlara) sahip işlevleri çağırırsınız. Ancak orijinal sorgu (MAXRECURSION = 100000000 ile çalıştırılırsa) hiçbir zaman EventID=101(ve 201, .., 901) satırını ziyaret edemez . Bu nedenle iki sorgu (orijinal ve çözümünüz) farklı sonuçlar döndürebilir (ilkinde 101 ile satır yok, 2'de evet)! Veya 101'i ziyaret edebilir, ancak 100. adımdan önce, çözümünüz satırdaki sonuçları iki kez daha içerecektir (yine farklı)
ypercubeᵀᴹ

2
Elbette veriler ardışık EventID değerlerine (1,2,, 3 ..., 99,100,101, ..) bağlı değilse. Bu durumda, özyinelemeli bir CTE'ye ihtiyacınız olmaz.
ypercubeᵀᴹ

Bu, bilinmeyen derinlik sorununu ... belirli bir DMS yolundan bir ağaç olarak satır kümesi almak gibi bir şey için nasıl çözer?
Savaş
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.