Làm thế nào để SQL Server xử lý dữ liệu cho một truy vấn khi không có đủ chỗ trong bộ đệm bộ đệm?


10

Câu hỏi của tôi là làm thế nào để SQL Server xử lý một truy vấn cần kéo nhiều khối lượng dữ liệu vào bộ đệm hơn so với không gian có sẵn? Truy vấn này sẽ chứa nhiều phép nối, do đó, tập kết quả không tồn tại ở định dạng này đã có trên đĩa và nó sẽ cần phải biên dịch kết quả. Nhưng ngay cả sau khi biên dịch, nó vẫn cần nhiều dung lượng hơn so với bộ đệm trong bộ đệm.

Tôi sẽ lấy một ví dụ. Giả sử bạn có một phiên bản SQL Server có tổng dung lượng Bộ đệm Cache 6GB khả dụng. Tôi chạy một truy vấn có nhiều phép nối đọc 7GB dữ liệu, làm thế nào SQL Server có thể đáp ứng yêu cầu này? Nó tạm thời lưu trữ dữ liệu trong tempdb? Nó có thất bại không? Nó có làm một cái gì đó chỉ đọc dữ liệu từ đĩa và biên dịch các phân đoạn tại một thời điểm không?

Ngoài ra, điều gì xảy ra nếu tôi đang cố gắng trả lại 7GB tổng dữ liệu, điều đó có thay đổi cách SQL Server xử lý không?

Tôi đã biết một số cách để giải quyết vấn đề này, tôi chỉ tò mò về cách SQL Server xử lý yêu cầu này trong nội bộ khi nó chạy như đã nêu.

Ngoài ra, tôi chắc chắn thông tin này tồn tại ở đâu đó, nhưng tôi đã không thành công trong việc tìm kiếm nó.


1
Theo thuật ngữ của layman, SQL Server sẽ lưu trữ các bảng công việc và kết quả xử lý nội bộ của chính nó trong tempdb. Các trang được đọc từ đĩa khi cần thiết. Các trang sẽ vẫn còn trong bộ nhớ cho đến khi chúng bị loại bỏ hoặc khi SQL sẵn sàng đưa chúng vào đĩa. Đây là khi bạn chạy một truy vấn lớn tempdb sẽ phát triển. Tôi đã thấy các truy vấn đưa một hệ thống đến đầu gối của nó vì tempdb được phép phát triển không được kiểm soát và tiêu thụ tất cả không gian còn lại trên ổ đĩa. Tôi biết điều này không chính xác 100%, chỉ cố gắng giải thích nó đơn giản. Phần sử dụng dữ liệu không phải là phần quản lý vị trí của dữ liệu đó
datagod

Câu trả lời:


13

Các trang được đọc vào bộ nhớ theo yêu cầu, nếu không có bộ nhớ trống, trang chưa sửa đổi cũ nhất sẽ được thay thế bằng trang đến.

Điều này có nghĩa là nếu bạn thực hiện một truy vấn yêu cầu nhiều dữ liệu hơn mức có thể phù hợp với bộ nhớ, nhiều trang sẽ có tuổi thọ rất ngắn trong bộ nhớ, dẫn đến rất nhiều I / O.

Bạn có thể thấy hiệu ứng này bằng cách xem bộ đếm "Tuổi thọ trang" trong Windows Performance Monitor. Hãy xem https://sqlperformance.com/2014/10/sql-performance/knee-jerk-page-life-Exectancy để biết một số chi tiết tuyệt vời về bộ đếm đó.

Trong các bình luận, bạn đã hỏi cụ thể điều gì xảy ra khi kết quả của truy vấn lớn hơn không gian bộ đệm có sẵn. Lấy ví dụ đơn giản nhất, select * from some_very_big_table;- giả sử bảng là 32 GB và max server memory (MB)được định cấu hình ở mức 24 GB. Tất cả 32GB dữ liệu bảng sẽ được đọc vào các trang trong bộ đệm trang một lần, được chốt, được định dạng vào các gói mạng và được gửi qua dây. Điều này xảy ra từng trang một; bạn có thể có 300 truy vấn như vậy chạy cùng một lúc và giả sử không có chặn nào xảy ra, dữ liệu cho mỗi truy vấn sẽ được đọc vào không gian bộ đệm trang, một trang và đưa vào dây nhanh nhất có thể yêu cầu và tiêu thụ dữ liệu. Khi tất cả dữ liệu từ mỗi trang đã được gửi lên dây, trang sẽ không được nối và sẽ nhanh chóng được thay thế bởi một số trang khác từ đĩa.

Trong trường hợp truy vấn phức tạp hơn, giả sử, ví dụ tổng hợp kết quả từ một số bảng, các trang sẽ được kéo vào bộ nhớ chính xác như trên theo yêu cầu của bộ xử lý truy vấn. Nếu bộ xử lý truy vấn cần không gian làm việc tạm thời để tính kết quả, nó sẽ biết rằng trả trước khi nó biên dịch một kế hoạch cho truy vấn và sẽ yêu cầu không gian làm việc (bộ nhớ) từ SQLOS . Tại một thời điểm nào đó, SQLOS (giả sử không hết thời gian ), cấp bộ nhớ đó cho bộ xử lý truy vấn, tại đó quá trình xử lý truy vấn sẽ tiếp tục. Nếu bộ xử lý truy vấn mắc lỗi trong ước tính dung lượng bộ nhớ cần yêu cầu từ SQLOS, thì có thể cần phải thực hiện "tràn vào đĩa"hoạt động, trong đó dữ liệu tạm thời được ghi vào tempdb ở dạng trung gian. Các trang đã được ghi vào tempdb sẽ được hủy theo dõi khi chúng được ghi vào tempdb để nhường chỗ cho các trang khác được đọc vào bộ nhớ. Cuối cùng, quá trình truy vấn sẽ trở về dữ liệu được lưu trữ trong tempdb, phân trang rằng bằng cách sử dụng chốt, vào các trang trong bộ đệm được đánh dấu miễn phí.

Tôi chắc chắn thiếu một tải các chi tiết rất kỹ thuật trong bản tóm tắt ở trên, nhưng tôi nghĩ rằng nắm bắt được bản chất của cách SQL Server có thể xử lý nhiều dữ liệu hơn mức có thể phù hợp với bộ nhớ.


Vì tò mò, loại truy vấn nào đang kéo 7GB dữ liệu? Tôi hy vọng đây là một quá trình hàng loạt.
datagod

Có lẽ không nhiều và bạn đúng, hy vọng nó sẽ là một quá trình hàng loạt. Tôi chỉ tò mò muốn xem SQL sẽ xử lý yêu cầu đó như thế nào
Dustin

5

Tôi không thể nói chính xác truy vấn của bạn sẽ làm gì trong kịch bản này nhưng SQL Server có một số tùy chọn tùy thuộc vào mức độ cần thiết.

  • Dữ liệu có thể "tràn" sang TempDB, điều này sẽ sử dụng đĩa của bạn
  • Các trang cũ có thể được đẩy ra khỏi bộ đệm của bạn
  • SQL Server có thể tải một số trang để đệm bộ đệm, sử dụng chúng, sau đó xoay các trang mới trong

Cách tốt nhất để tìm hiểu điều gì sẽ xảy ra là tạo kịch bản trong môi trường dev và tìm hiểu.


2

Câu hỏi của tôi là làm thế nào để SQL Server xử lý một truy vấn cần kéo thêm khối lượng dữ liệu vào bộ đệm bộ đệm thì có sẵn dung lượng trống

Để trả lời phần cụ thể này, hãy để tôi nói cho bạn biết cách thức này được quản lý. Các trang có kích thước 8KB. Khi bạn chạy truy vấn yêu cầu tập dữ liệu lớn và yêu cầu nhiều trang được đưa vào bộ nhớ, SQL Server sẽ không mang tất cả các trang trong một lần. Nó sẽ xác định vị trí các trang cụ thể và đưa từng trang 8KB vào bộ nhớ đọc dữ liệu từ nó và đưa ra kết quả và điều này sẽ tiếp tục, giả sử nó phải đối mặt với tình huống trong đó bộ nhớ cũ sẽ bị xóa đĩa như @Max chỉ ra. Như bạn đã đoán chính xác, bộ nhớ thấp này có thể làm chậm mọi thứ vì sẽ mất một thời gian để xóa các trang cũ. Đây là nơi trạm kiểm soát và Lazywriterđi vào hình ảnh. Lazywriter là của họ để đảm bảo một số bộ nhớ trống luôn ở đó để đưa các trang mới vào đĩa. Khi gặp bộ đệm miễn phí thấp, nó được kích hoạt và tạo không gian trống để trở thành trang mới.

BIÊN TẬP

Tôi hiểu điều đó, nhưng phần gây khó khăn cho tôi một chút là điều gì sẽ xảy ra nếu bạn tham gia \ lọc dữ liệu và những kết quả đó vượt quá kích thước của bộ đệm.

Bộ nhớ để nối và lọc được quyết định ngay cả trước khi truy vấn chạy và giả sử thực sự có tình trạng khủng hoảng bộ nhớ và bộ nhớ cần thiết để chạy hoạt động không có sẵn Bộ xử lý SQL Server sẽ cấp "bộ nhớ bắt buộc"

Bộ nhớ bắt buộc: Bộ nhớ tối thiểu cần thiết để chạy sắp xếp và băm tham gia. Nó được gọi là bắt buộc vì một truy vấn sẽ không bắt đầu mà không có bộ nhớ này. Máy chủ SQL sử dụng bộ nhớ này để tạo cấu trúc dữ liệu nội bộ để xử lý sắp xếp và băm tham gia.

Vì vậy, ít nhất truy vấn sẽ bắt đầu chạy nhưng trong thời gian chạy, rất có thể kết quả trung gian bị tràn sang Tempdb khiến nó chậm. Tôi thực sự khuyên bạn nên đọc Tìm hiểu cấp bộ nhớ truy vấn


Tôi hiểu điều đó, nhưng phần gây khó khăn cho tôi một chút là điều gì sẽ xảy ra nếu bạn tham gia \ lọc dữ liệu và những kết quả đó vượt quá kích thước của bộ đệm. Dữ liệu sẽ cần phải được biên dịch để tạo tập trả về, nhưng tập trả về lớn hơn kích thước của bộ đệm. Có phải vẫn là các trang chu kỳ nội bộ thông qua bộ đệm cho đến khi nó tạo ra kết quả cuối cùng? Tôi nghĩ rằng nó sẽ ghi kết quả vào tempdb vì nó vượt quá bộ đệm và sau đó đọc từ đĩa đó, nhưng không biết đó có phải là trường hợp không
Dustin

2
@Dustin Đã chỉnh sửa câu trả lời của tôi, vui lòng kiểm tra
Shanky
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.