Tạo chỉ mục không phân cụm trên máy chủ SQL cột không tính toán


10

Tôi đang vật lộn để tìm bất kỳ tài liệu nào về cách SQL Server thực sự lưu trữ một cột được tính toán không tồn tại.

Lấy ví dụ sau:

--SCHEMA
CREATE TABLE dbo.Invoice
(
    InvoiceID INT IDENTITY(1, 1) PRIMARY KEY,
    CustomerID INT FOREIGN KEY REFERENCES dbo.Customer(CustomerID),
    InvoiceStatus NVARCHAR(50) NOT NULL,
    InvoiceStatusID AS CASE InvoiceStatus 
                         WHEN 'Sent' THEN 1 
                         WHEN 'Complete' THEN 2
                         WHEN 'Received' THEN 3
                       END
)
GO

--INDEX
CREATE NONCLUSTERED INDEX IX_Invoice ON Invoice
(
    CustomerID ASC
)
INCLUDE
(
    InvoiceStatusID
)
GO

Tôi nhận được rằng nó được lưu trữ ở cấp độ lá, nhưng nếu giá trị không được duy trì thì làm sao mọi thứ được lưu trữ? Làm thế nào để chỉ mục giúp SQL Server tìm thấy các hàng này trong tình huống này?

Bất kỳ trợ giúp đánh giá rất cao,

Cảm ơn nhiều,

BIÊN TẬP:

Cảm ơn Brent & Aaron đã trả lời điều này, đây là PasteThePlan cho thấy rõ những gì họ đã giải thích.


5
Nó không được duy trì trong các trang dữ liệu của bảng, nhưng nó vẫn tồn tại trong các trang của chỉ mục .
Aaron Bertrand

Các cột không tính toán không tồn tại không được lưu trữ trong bảng. Chúng là những cột ảo. Giá trị của chúng được tính toán lại mỗi khi chúng được tham chiếu trong truy vấn. thấy ref này .
Kin Shah

Câu trả lời:


11

Khi SQL Server tạo chỉ mục trên trường được tính toán, trường được tính sẽ được ghi vào đĩa tại thời điểm đó - nhưng chỉ trên các trang 8K của chỉ mục đó. SQL Server có thể tính toán InvoiceStatusID khi nó đọc qua chỉ mục được nhóm - không cần phải ghi dữ liệu đó vào chỉ mục được nhóm.

Khi bạn xóa / cập nhật / chèn các hàng trong dbo.Invoice, dữ liệu trong các chỉ mục được cập nhật. (Khi InvoiceStatus thay đổi, SQL Server cũng biết cập nhật IX_Invoice.)

Cách tốt nhất bạn có thể tự mình nhìn thấy điều này là thực sự làm điều đó: tạo các đối tượng này và thực hiện các cập nhật chạm vào trường InvoiceStatusID. Đăng kế hoạch thực hiện (PasteThePlan.com rất hữu ích cho việc này) nếu bạn muốn trợ giúp xem nơi cập nhật chỉ mục đang diễn ra.


1
@ Uberzen1 Không, như ông giải thích, nó được ghi vào các trang chỉ mục tại thời điểm chèn / cập nhật. Nó không phải tính toán lại bất cứ điều gì nếu chỉ mục được sử dụng để truy cập vào cột.
Aaron Bertrand

Ah! Tôi đang ở bên bạn, xin lỗi!
Uberzen1

6
@blobble tốt, không có ý xúc phạm, nhưng tôi không nghĩ đó là về Brent. Họ có thể dán cùng một XML vào dropbox, các diễn đàn MSDN, ở đây, về cơ bản là bất cứ nơi nào trực tuyến ... có phải mọi dịch vụ trực tuyến hiện nay đều phải chịu trách nhiệm về những bí mật có thể được tiết lộ bởi những người tải lên các tệp ở đó không?
Aaron Bertrand

2
@blobble yeah, bạn không thể ngăn mọi người bỏ qua. Nhân tiện, hãy theo dõi tôi trên Instagram - Tôi là BrentO - và tôi chia sẻ hình ảnh về bữa sáng của mình ở đó. ;-)
Brent Ozar

4
@blobble trong liên kết Quyền riêng tư, nó ghi: Dữ liệu bạn sao chép / dán vào đây là công khai . Bất cứ ai cũng có thể đọc nó. Không có bảo mật.
ypercubeᵀᴹ

8

Giá trị cho một cột được tính toán, không được lập chỉ mục không được duy trì trong các trang dữ liệu của bảng , nhưng nó được duy trì trong các trang của chỉ mục . Nó vẫn không tồn tại trong bảng, bất kể nó được duy trì ở 0, 1 hay nhiều chỉ mục.

Chỉ để minh họa mô tả của Brent, lấy ví dụ bạn đã đưa ra, hãy chèn một hàng:

INSERT dbo.Invoice(CustomerID, InvoiceStatus) VALUES(1,N'Sent');

Bây giờ, hãy xem các trang chỉ mục:

DBCC TRACEON(3604, -1);
DBCC IND(N'dbname', N'dbo.Invoice', 2);

(Rõ ràng là thay đổi dbnamevà ID chỉ mục có thể không phải là 2 trong trường hợp của bạn.)

Đầu ra (của bạn chắc chắn sẽ khác nhau):

nhập mô tả hình ảnh ở đây

Và cuối cùng, hãy kiểm tra trang cho PageType2:

DBCC PAGE(7, 1, 584, 3);

(Bạn có thể sẽ cần thay đổi 7 để khớp với id cơ sở dữ liệu của mình và nếu bạn có nhiều tệp dữ liệu, bạn có thể cần thay đổi đối số thứ hai để khớp với PageFIDkết quả đầu tiên.)

Đầu ra:

nhập mô tả hình ảnh ở đây

Đó là trên trang chỉ mục.


Rất tuyệt, cảm ơn Aaron. Lý do tôi đặt câu hỏi ban đầu là tôi gặp một số rắc rối thực sự khi triển khai một chỉ mục tương tự trong thế giới thực và muốn hiểu chính xác những gì đang diễn ra dưới mui xe để tôi có thể tìm ra vấn đề. Điều này giúp rất nhiều, cảm ơn!
Uberzen1

1
@ Uberzen1 Bạn có thể định nghĩa "rắc rối thực sự" không? Bạn sẽ gửi một câu hỏi về vấn đề đó ?
Aaron Bertrand

Tôi có thể làm, tôi sẽ tự mình nghiên cứu sâu hơn về nó, nhưng tôi chỉ muốn hiểu rõ hơn về những gì mà câu lệnh tạo chỉ mục đang làm chính xác. TLDR là; Tôi có một bảng lớn tương tự như bảng hóa đơn ở trên, nó có khoảng 400 triệu bản ghi và thật không may, cột OrderStatus bị tát ngay giữa nó, khiến việc lập chỉ mục v.v ... hơi đau. Chúng tôi đã thêm một cột được tính toán cho đến bây giờ chúng tôi cuối cùng sẽ tiếp tục và di chuyển trường varchar ra khỏi bảng của chính nó. 1/2
Uberzen1

5
@ Uberzen1 Vâng, bởi vì cột được tính toán thực sự được vật chất hóa trên đĩa khi ghi vào chỉ mục, tất cả hoạt động đó phải được ghi lại. Một cách giải quyết khác có thể là dừng dựa vào cột được tính toán - đặt biểu thức đó vào dạng xem hoặc truy vấn ad hoc và nếu đó không phải là một tùy chọn bạn có thể tạo một cột nullable mới, hãy cập nhật nó trong các đoạn (để tránh việc ghi nhật ký) , sau đó thả cột được tính toán, đổi tên cột mới và thay đổi DML của bạn để viết thủ công. Nhưng thực sự vì đó là thông tin dư thừa mà bạn có thể lấy từ dữ liệu hiện có, tôi sẽ chọn tùy chọn đầu tiên.
Aaron Bertrand

2
Cảm ơn rất nhiều Aaron. Tôi rất vui vì bạn đã đề cập đến việc đưa ra một quan điểm trước nó vì đó cũng là giải pháp của tôi, có lẽ đã đến lúc xem lại ý tưởng đó!
Uberzen1

7

Thuộc tính PERSISTEDcho một cột được tính toán liên quan đến việc các giá trị được duy trì trong bảng (chỉ mục cụm hay heap) và không xem các giá trị có được duy trì trong chỉ mục hay không.

CREATE INDEXcác yêu cầu cho các giới hạn về các cột và chỉ mục được tính toán:

Các cột được tính toán mang tính xác định và chính xác hoặc không chính xác có thể được bao gồm các cột. Các cột được tính toán có nguồn gốc từ hình ảnh, ntext, văn bản, varchar (max), nvarchar (max), varbinary (max) và xml có thể được bao gồm trong các cột không khóa miễn là các loại dữ liệu cột được tính toán được cho phép cột. Để biết thêm thông tin, hãy xem Chỉ mục trên Cột được tính toán.

Không có giới hạn về việc cột tính toán có được duy trì hay không.

và hơn nữa (không bao gồm nhưng về các cột được tính toán trong phần chính của chỉ mục):

Chỉ mục có thể được tạo trên các cột được tính toán. Ngoài ra, các cột được tính toán có thể có thuộc tính PERSISTED. Điều này có nghĩa là Công cụ cơ sở dữ liệu lưu trữ các giá trị được tính toán trong bảng và cập nhật chúng khi bất kỳ cột nào khác mà cột được tính phụ thuộc được cập nhật. Công cụ cơ sở dữ liệu sử dụng các giá trị bền vững này khi nó tạo một chỉ mục trên cột và khi chỉ mục được tham chiếu trong một truy vấn.

Để lập chỉ mục một cột được tính toán, cột được tính phải (được) xác định và chính xác. Tuy nhiên, việc sử dụng thuộc PERSISTEDtính sẽ mở rộng loại cột được tính toán có thể lập chỉ mục để bao gồm:

...

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.