Trong khi tôi tôn trọng người đệ trình, tôi không đồng ý với câu trả lời được cung cấp và không vì "lý do tôn giáo". Nói cách khác, tôi tin rằng không có cơ sở nào mà Microsoft cung cấp làm giảm nhu cầu hướng dẫn sử dụng các thủ tục được lưu trữ.
Bất kỳ hướng dẫn nào được cung cấp cho nhà phát triển ưu tiên sử dụng các truy vấn SQL văn bản thô phải có nhiều cảnh báo, vì vậy tôi nghĩ rằng lời khuyên khôn ngoan nhất là khuyến khích rất nhiều việc sử dụng Quy trình được lưu trữ và không khuyến khích các nhóm nhà phát triển của bạn tham gia vào thực tiễn về việc nhúng các câu lệnh SQL trong mã hoặc gửi các yêu cầu SQL dựa trên văn bản thô, cũ, bên ngoài SQL SPROCs (các thủ tục được lưu trữ).
Tôi nghĩ rằng câu trả lời đơn giản cho câu hỏi tại sao sử dụng một XUÂN là do người nộp đã phỏng đoán: các XUÂN được phân tích cú pháp, tối ưu hóa và biên dịch. Như vậy, các gói truy vấn / thực thi của chúng được lưu trong bộ nhớ cache vì bạn đã lưu một biểu diễn tĩnh của truy vấn và thông thường, bạn sẽ chỉ thay đổi nó theo các tham số, điều này không đúng trong trường hợp các câu lệnh SQL được sao chép / dán có khả năng biến hình từ trang này sang trang khác và thành phần / tầng và thường được biến đổi theo phạm vi mà các bảng khác nhau, thậm chí tên cơ sở dữ liệu, có thể được chỉ định từ cuộc gọi đến cuộc gọi. Cho phép loại quảng cáo động nàyViệc gửi SQL, làm giảm đáng kể khả năng DB Engine sử dụng lại kế hoạch truy vấn cho các câu lệnh ad hoc của bạn, theo một số quy tắc rất nghiêm ngặt. Ở đây, tôi đang phân biệt giữa các truy vấn ad hoc động (theo tinh thần của câu hỏi được nêu ra) so với việc sử dụng Hệ thống sp_executesql hiệu quả của Hệ thống XUÂN.
Cụ thể hơn, có các thành phần sau:
- Các gói truy vấn nối tiếp và song song không giữ ngữ cảnh người dùng và cho phép sử dụng lại bởi công cụ DB.
- Bối cảnh thực thi cho phép người dùng mới sử dụng lại các gói truy vấn với các tham số dữ liệu khác nhau.
- Bộ đệm thủ tục là những gì mà công cụ DB truy vấn để tạo ra hiệu quả mà chúng ta tìm kiếm.
Khi một câu lệnh SQL được phát ra từ một trang web, được gọi là "câu lệnh ad hoc", công cụ sẽ tìm một kế hoạch thực hiện hiện có để xử lý yêu cầu. Bởi vì đây là văn bản được gửi từ người dùng, nó sẽ được nhập, phân tích cú pháp, biên dịch và thực thi, nếu nó hợp lệ. Tại thời điểm này, nó sẽ nhận được một chi phí truy vấn bằng không. Chi phí truy vấn được sử dụng khi công cụ DB sử dụng thuật toán của nó để xác định kế hoạch thực hiện nào để đuổi khỏi bộ đệm.
Theo mặc định, các truy vấn đặc biệt nhận được giá trị truy vấn gốc bằng 0. Sau khi thực hiện chính xác văn bản truy vấn ad hoc chính xác, bởi một quá trình người dùng khác (hoặc cùng một quy trình), chi phí truy vấn hiện tại được đặt lại thành chi phí biên dịch ban đầu. Vì chi phí biên dịch truy vấn ad hoc của chúng tôi bằng không, nên điều này không tốt cho khả năng sử dụng lại. Rõ ràng, số 0 là số nguyên có giá trị thấp nhất, nhưng tại sao nó lại bị đuổi?
Khi áp lực bộ nhớ phát sinh và nếu bạn có một trang web thường được sử dụng, công cụ DB sẽ sử dụng thuật toán dọn dẹp để xác định cách nó có thể lấy lại bộ nhớ mà bộ đệm thủ tục đang sử dụng. Nó sử dụng chi phí truy vấn hiện tại để quyết định kế hoạch nào để đuổi. Như bạn có thể đoán, các gói có chi phí bằng 0 là lần đầu tiên bị đuổi khỏi bộ đệm vì về cơ bản số 0 có nghĩa là "không có người dùng hiện tại hoặc tham chiếu đến gói này".
- Lưu ý: Kế hoạch thực hiện ad hoc - Chi phí hiện tại được tăng theo từng quy trình của người dùng, bằng chi phí biên dịch ban đầu của kế hoạch. Tuy nhiên, không có chi phí tối đa của kế hoạch có thể nhiều hơn chi phí biên dịch ban đầu của nó ... trong trường hợp truy vấn ad hoc ... bằng không. Vì vậy, nó sẽ được "tăng" bởi giá trị đó ... bằng không - điều đó có nghĩa là nó sẽ vẫn là gói chi phí thấp nhất.
Do đó, nhiều khả năng kế hoạch như vậy sẽ bị trục xuất trước tiên khi áp lực bộ nhớ xuất hiện.
Vì vậy, nếu bạn có một máy chủ tích hợp nhiều bộ nhớ "vượt quá nhu cầu của bạn", bạn có thể không gặp phải vấn đề này thường xuyên như một máy chủ bận rộn chỉ có bộ nhớ "đủ" để xử lý khối lượng công việc của nó. (Xin lỗi, dung lượng bộ nhớ máy chủ và việc sử dụng có phần chủ quan / tương đối, mặc dù thuật toán thì không.)
Bây giờ, nếu tôi thực sự không chính xác về một hoặc nhiều điểm, tôi chắc chắn sẵn sàng để được sửa chữa.
Cuối cùng, tác giả đã viết:
"Bây giờ chúng tôi đã tối ưu hóa mức câu lệnh, do đó, một truy vấn được tham số hóa chính xác đến từ một ứng dụng có thể tận dụng cùng một kế hoạch thực hiện như truy vấn đó được nhúng trong một thủ tục được lưu trữ."
Tôi tin rằng tác giả đang đề cập đến tùy chọn "tối ưu hóa cho khối lượng công việc ad hoc".
Nếu vậy, tùy chọn này cho phép một quy trình gồm hai bước để tránh ngay lập tức gửi gói truy vấn đầy đủ đến bộ đệm Thủ tục. Nó chỉ gửi một truy vấn nhỏ hơn ở đó. Nếu một cuộc gọi truy vấn chính xác được gửi trở lại máy chủ trong khi cuống truy vấn vẫn còn trong bộ đệm thủ tục, kế hoạch thực hiện truy vấn đầy đủ sẽ được lưu vào bộ đệm thủ tục, tại thời điểm đó. Điều này giúp tiết kiệm bộ nhớ, trong các sự cố áp suất bộ nhớ, có thể cho phép thuật toán trục xuất đuổi sơ khai của bạn ít thường xuyên hơn so với gói truy vấn lớn hơn được lưu trữ. Một lần nữa, điều này phụ thuộc vào bộ nhớ và sử dụng máy chủ của bạn.
Tuy nhiên, bạn phải bật tùy chọn này vì nó tắt theo mặc định.
Cuối cùng, tôi muốn nhấn mạnh rằng, thông thường, chính các nhà phát triển sẽ nhúng SQL vào các trang, thành phần và các vị trí khác, là vì họ muốn linh hoạt và gửi truy vấn SQL động đến công cụ cơ sở dữ liệu. Do đó, trong Trường hợp sử dụng trong thế giới thực, việc gửi cùng một văn bản, cuộc gọi qua cuộc gọi, dường như không xảy ra như bộ đệm / hiệu quả mà chúng tôi tìm kiếm, khi gửi truy vấn ad hoc đến SQL Server.
Để biết thêm thông tin, vui lòng xem:
https://technet.microsoft.com/en-us/l
Library /
ms181055 (v = sql.105) .aspx http://sqlmag.com/database-performance-tuning/don-t-fear-dynamic-sql
Tốt nhất,
Henry