Thay đổi mặc định toàn hệ thống để tối đa hóa


12

Làm cách nào để thay đổi giá trị mặc định trên toàn hệ thống MAXRECURSION?

Theo mặc định là 100, nhưng tôi cần tăng nó lên 1000.

Tôi không thể sử dụng các gợi ý truy vấn vì tôi đang sử dụng một chương trình lấy truy vấn của mình và thực hiện nó cho tôi và thật không may, tôi không thể vượt qua giới hạn này.

Tuy nhiên, tôi có quyền quản trị viên trên máy chủ. Tôi đã chọc vào các khía cạnh của máy chủ, nhưng tôi không thấy bất cứ điều gì ở đó liên quan đến các tùy chọn truy vấn hoặc đệ quy. Tôi giả sử có được một vị trí ở đâu đó nơi tôi có thể cập nhật mặc định toàn hệ thống.

Có ý kiến ​​gì không?


3
Tôi chỉ muốn kiểm tra bạn hiểu giới hạn 100 chỉ dành cho lượt xem và chức năng và bạn có thể sử dụng quy trình được lưu trữ và ghi đè cục bộ ở đó không? Có bất kỳ nhu cầu cụ thể để sử dụng một chức năng? Vì đệ quy khá kém hiệu quả, tôi cũng sẽ đề nghị đi bộ phân cấp chỉ một lần và lưu trữ đầu ra trong một bảng. Sau đó, bạn có thể tạo một hàm tham chiếu đến bảng đó. Bạn nghĩ sao?
wBob

Câu trả lời:


10

Nếu các truy vấn của bạn có hình dạng chung, bạn có thể thêm gợi ý tối đa được yêu cầu bằng một hoặc nhiều hướng dẫn kế hoạch.

Có thể có một sở trường để làm cho họ đúng. Nếu bạn thêm chi tiết truy vấn cụ thể vào câu hỏi của bạn, chúng tôi có thể giải quyết vấn đề đó cho bạn. Thông thường, bạn sẽ theo dõi SQL thực sự đánh vào máy chủ hoặc lấy một biểu mẫu được tham số hóa bằng cách sử dụng thủ tục tích hợp sys.sp_get_query_template , sau đó tạo hướng dẫn kế hoạch TEMPLATE và / hoặc OBRI / SQL.

Xem tài liệu để biết thêm thông tin:

Hướng dẫn về kế hoạch sẽ cần được xác nhận lại bất cứ khi nào mã ứng dụng thay đổi và khi SQL Server được vá hoặc nâng cấp. Đây chỉ là một phần của chu kỳ kiểm tra bình thường của bạn.

Lưu ý rằng xác thực hướng dẫn kế hoạch bằng sys.fn_validate_plan_guide có thể báo cáo sai một lỗi nếu câu lệnh được hướng dẫn tham chiếu bảng tạm thời. Xem câu hỏi này:

Xác thực hướng dẫn kế hoạch với fn_validate_plan_guide cho kết quả dương tính giả

Các Kế hoạch Hướng dẫn thành côngKế hoạch Hướng dẫn Không thành công Profiler và sự kiện mở rộng các lớp học cũng có thể được sử dụng để theo dõi các ứng dụng hướng dẫn kế hoạch.

Connect được nghỉ hưu trước khi cải tiến đề nghị sản phẩm Cho phép giới hạn MAXRECURSION giá trị khác hơn 100 cho quan điểm và UDFs bởi Steve Kass đã được thực hiện. Nếu bạn muốn tiếp tục với Microsoft ngay bây giờ, hãy xem các tùy chọn tại trợ giúp và phản hồi của SQL Server .


Điều này thật khó chịu và không trả lời câu hỏi thay vào đó chôn chúng tôi vào một lỗ tài liệu thỏ. EF Core (một ORM điển hình) tạo ra các truy vấn cho bạn ngay cả khi bạn cung cấp cho nó một câu lệnh SQL thô, nó bao bọc rằng trong phần cha mẹ chọn, bất kỳ ai sử dụng EF Core đều gặp phải vấn đề này. Giải pháp của bạn là "lập kế hoạch truy vấn của bạn".
Chiến tranh

@War Đó là câu trả lời tốt nhất tôi có thể đưa ra cho câu hỏi cụ thể này với chi tiết được cung cấp. Cách duy nhất tôi biết để thêm gợi ý đệ quy tối đa là thông qua một điều SQL Server gọi là Hướng dẫn kế hoạch, không liên quan gì đến việc "lập kế hoạch truy vấn của bạn". Nếu bạn có một câu hỏi cụ thể của riêng bạn, vui lòng hỏi riêng với một ví dụ có thể lặp lại tối thiểu .
Paul White 9

9

Nếu bạn hoàn toàn phải sử dụng một hàm (giới hạn của công cụ ETL như bạn ngụ ý), bạn có thể chỉ định OPTIONlà một phần của hàm có giá trị bảng nhiều câu lệnh, ví dụ như thế này:

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

Điều này cũng làm việc cho tôi khi được bao bọc trong một khung nhìn như bạn đề xuất các công cụ ETL của bạn. Không có cách nào để thay đổi toàn hệ thống này, nhưng vì đệ quy có thể không hiệu quả, đây có lẽ là một điều tốt. Bạn không thể chỉ định một gợi ý truy vấn (sử dụng OPTION) trong phần thân của hàm có giá trị bảng nội tuyến, như trong ví dụ của bạn.

Cân nhắc thay đổi quy trình của bạn để đi theo cấu trúc phân cấp chỉ một lần khi bạn nhận được các Tập và lưu trữ đầu ra trong một bảng quan hệ. Bạn có thể sử dụng một Proc được lưu trữ để làm điều này để không gặp phải giới hạn này.

Tôi cũng nghĩ rằng có thể có một lỗi trong mã của bạn: nếu CTE của bạn tham gia vào personId và đệ quy trên eventId, eventId 101 sẽ xuất hiện hai lần tôi nghĩ, như một bản sao. Có thể tôi đã hiểu sai mã của bạn, hãy cho tôi biết bạn nghĩ gì.

HTH


điều này không hoạt động vì tham số "TÙY CHỌN" phải được áp dụng ở cấp câu lệnh và câu lệnh được đề cập là lệnh gọi hàm, điều này sẽ trả về một ngoại lệ.
Chiến tranh

0

Tôi lấy cảm hứng từ chủ đề này .

Đây là những gì tôi đã làm để giải quyết vấn đề.

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

Sau đó, tôi gọi hàm này như thế này:

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

Bằng cách này, không có logic CTE nào của tôi phải được lặp lại và tôi không phải trả thêm bất cứ điều gì về hiệu suất. Đó là một phiền toái rằng nó phải được thực hiện theo cách này, nhưng tôi có thể sống với nó.


3
Tôi không thấy cách này giải quyết vấn đề đệ quy. Việc gọi hàm không được đệ quy.
ypercubeᵀᴹ

@ ypercubeᵀᴹ - bit đệ quy của CTE đi đến nơi tôi có dấu chấm lửng - logic đệ quy đặc biệt của tôi không thực sự liên quan đến vấn đề, nhưng thực tế bạn có thể cho rằng CTE là đệ quy. Các wheređiều khoản sau ellipsis cản trở quá nhiều recursions xảy ra bằng cách sử dụng tham số chức năng như một hạn chế. Tôi đoán rằng nên có một tuyên bố sau khi định nghĩa CTE, mặc dù. Tôi sẽ thêm nó.
carl.anderson

3
Tôi hiểu rất rõ rằng CTE là đệ quy. Vấn đề là việc gọi (gọi hàm) không được đệ quy . Ví dụ: bạn gọi các hàm có điểm bắt đầu (hàng) bằng EventID=1(và 101,201, ... 901). Nhưng truy vấn ban đầu (nếu được chạy với MAXRECURSION = 100000000) có thể không bao giờ truy cập vào hàng với EventID=101(và 201, .., 901). Vì vậy, hai truy vấn (bản gốc và giải pháp của bạn) có thể trả về các kết quả khác nhau (không có hàng nào với 101 trong lần đầu tiên, có trong lần thứ 2)! Hoặc nó có thể truy cập 101 nhưng trước bước 100, vì vậy giải pháp của bạn sẽ bao gồm hàng hai lần trong kết quả (lại khác)
ypercubeᵀᴹ

2
Tất nhiên, trừ khi dữ liệu được kết nối các giá trị EventID tuần tự của thorugh (1,2, 3 ..., 99,100,101, ..). Trong trường hợp đó, bạn hoàn toàn không cần CTE đệ quy.
ypercubeᵀᴹ

Làm thế nào điều này giải quyết vấn đề độ sâu chưa biết cho một cái gì đó như ... lấy một cây từ một đường dẫn DMS nhất định dưới dạng một hàng?
Chiến tranh
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.