Có phải những người khác đã ra khỏi các hàng trường Các trường được đọc khi sử dụng một chỉ mục cụm?


10

Tôi biết rằng khi VARCHAR(MAX)/NVARCHAR(MAX)các cột được sử dụng, dữ liệu sẽ được lưu trữ out of the row- hàng dữ liệu sẽ có một con trỏ đến một vị trí khác nơi 'giá trị lớn' được lưu trữ.

Tôi có những câu hỏi sau:

  1. Là mỗi lĩnh vực được lưu trữ out of the rowhoặc chỉ maxnhững người?
  2. Nếu bạn đang sử dụng clustered indexbảng để đọc toàn bộ bản ghi, thì các trường cũng được lưu ngoài hàng có đọc không?

VARCHAR (MAX) hoặc NVARCHAR (MAX) được coi là "loại giá trị lớn". Các loại giá trị lớn thường được lưu trữ 'ngoài hàng'. Nó có nghĩa là ...


2
Trường hợp đó trích dẫn cuối cùng đến từ đâu? Nó không đúng.
Paul White 9


3
Toàn văn trong luồng MSDN gốc (của Jacob Sebastian) là chính xác. "Báo giá" Stack Overflow mất khá nhiều thứ đó. Phần nhỏ mà bạn đã trích dẫn ở trên bỏ qua tất cả các bit quan trọng :)
Paul White 9

Câu trả lời:


13

Tôi biết rằng khi VARCHAR(MAX)/NVARCHAR(MAX)các cột được sử dụng, dữ liệu được lưu trữ ngoài hàng ...

Trên thực tế, điều đó phụ thuộc vào cài đặt của large value types out of rowtùy chọn, có thể được đặt bằng cách sử dụng sp_tableoption. Từ tài liệu :

Chiết xuất BOL

Các mặc định là dành cho MAXcác giá trị được lưu trữ trong hàng , lên đến 8000 byte, nếu họ phù hợp. Trừ khi bạn đã sử dụng sp_tableoptionđể thay đổi mặc định, MAXrất có thể dữ liệu của bạn sẽ được lưu liên tiếp.

Điều đó nói rằng, việc sử dụng MAXcác loại dữ liệu cho các giá trị sẽ không bao giờ vượt quá 8000 byte - thực tế là sử dụng loại không phải MAX. Ngoài bất cứ điều gì khác, hiệu suất thường kém hơn đáng kể khi xử lý các MAXloại, vì SQL Server phải được chuẩn bị để đối phó với dữ liệu có thể có kích thước lên tới 2GB.

Là mỗi trường được lưu trữ ngoài hàng hoặc chỉ những trường tối đa?

Chỉ có MAXnhững người. Ngoài ra, nếu một MAXcột liên tiếp trước đó được di chuyển ra khỏi hàng, chỉ có cột đó trong hàng đó bị ảnh hưởng. Nó được thay thế trong hàng bằng một con trỏ tới LOBcấu trúc off-row . Cũng có trường hợp các cột không MAX có thể được chuyển ra khỏi hàng.

Nếu bạn đang sử dụng chỉ mục được nhóm của bảng để đọc toàn bộ bản ghi, thì các trường cũng được lưu trữ ngoài hàng đã đọc chưa?

Quét chỉ mục được nhóm đi qua dữ liệu liên tiếp. Nếu dữ liệu ngoài hàng là cần thiết cho truy vấn, nó được tra cứu bằng con trỏ liên tiếp.


Điều này luôn luôn đúng - Scanning the clustered index traverses only in-row data.? Ví dụ: nếu bạn muốn hiển thị các NVARCHAR(MAX)giá trị trường, làm thế nào có thể chỉ hoạt động với in-row-data(nếu các giá trị được lưu trữ ngoài hàng)? Hoặc khi bạn đang sử dụng chỉ mục được nhóm (vì không có chỉ mục che phủ) nhưng bạn sẽ không đến workvới NVARCHAR(MAX)trường, SQL Server đủ thông minh để thấy điều đó và bỏ qua việc tìm kiếm out-of-rowdữ liệu?
gotqn

Cảm ơn câu trả lời. Vì vậy, cuối cùng, nếu bạn có hai cột - intnvarchar(max)và bạn đang chọn chỉ có intcột, SQL Server không lãng phí tài nguyên để readcác out-of-rowdữ liệu như nó biết bạn sẽ không sử dụng nó?
gotqn

Cảm ơn rất nhiều. Điều đó thật tuyệt. Có vẻ như, bằng cách sử dụng, sp_tableoptionbạn có thể đưa ra khỏi bảng mọi thứ thường không được sử dụng để giảm kích thước của hàng, khi rất nhiều chỉ mục được tìm kiếm / quét được thực hiện.
gotqn

3
@gotqn Vâng. Off-hàng là mặc định cho các loại LOB cũ text, ntextimage. Tất nhiên, bạn cũng có thể lưu trữ các loại lớn trong một bảng riêng biệt.
Paul White 9

4

Hành vi này đối với lưu trữ đối tượng lớn có thể được kiểm soát bằng cài đặt bảng:

exec sp_tableoption N'MyTable', 'large value types out of row', <'ON' or 'OFF'>

Tài liệu tham khảo trong tài liệu SQL Server 2012 có tại: http://msdn.microsoft.com/en-us/l Library / ms173530.aspx

Do đó, bạn có thể kiểm soát nơi không gian được sử dụng, liên tiếp hoặc được lưu trữ ngoài hàng.


Cảm ơn, tôi thực sự không biết rằng bạn có thể kiểm soát điều này.
gotqn
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.