SQL Server đã được hơn 30 năm và tôi đã làm việc với SQL Server gần như lâu rồi. Kalen trình bày các bản quét trong Phần Một của SQL Server Internals:Problematic Operators.
Tôi đã thấy rất nhiều thay đổi trong nhiều năm (và nhiều thập kỷ!) Và các phiên bản của sản phẩm đáng kinh ngạc này. Trong các bài đăng này, tôi sẽ chia sẻ với bạn cách tôi xem xét một số tính năng hoặc khía cạnh của SQL Server, đôi khi cùng với một chút quan điểm lịch sử.
Điều chỉnh các truy vấn SQL Server của bạn là một trong những điều tốt nhất bạn có thể làm để có hiệu suất tốt hơn và tối ưu hóa chẩn đoán máy chủ SQL. Nhưng điều chỉnh là một chủ đề rất lớn! Biết chính xác cách điều chỉnh theo cách tốt nhất có thể không chỉ đòi hỏi kiến thức toàn diện về dữ liệu và khối lượng công việc của bạn, mà còn phải biết cách SQL Server thực sự đưa ra các lựa chọn thực thi kế hoạch. Vì vậy, bạn có thể làm gì nếu bạn không phải là chuyên gia về SQL Server Internals? Một điều bạn có thể làm là dựa vào những người là chuyên gia, cũng như các công cụ được viết bởi các chuyên gia. Các công cụ như Quest Spotlight Cloud Tuning Pack có thể cung cấp cho bạn một số đề xuất tuyệt vời để bắt đầu trên con đường đạt được hiệu suất truy vấn tốt hơn. Tất nhiên, không có công cụ bên ngoài nào biết dữ liệu của bạn và tất cả các chi tiết về tất cả khối lượng công việc của bạn, vì vậy bạn luôn nên kiểm tra kỹ lưỡng bất kỳ đề xuất nào mà bạn quyết định triển khai.
Trong các bài viết này về các toán tử có vấn đề, tôi sẽ cho rằng bạn có một số kiến thức cơ bản về cấu trúc chỉ mục của SQL Server. Dưới đây là một số thông tin hữu ích:
- Một bảng không có chỉ mục được phân nhóm được gọi là một đống và không có thứ tự. Không có hàng đầu tiên hoặc hàng cuối cùng. Một đống chỉ là một loạt các hàng không theo thứ tự cụ thể.
- Cấp độ lá của một chỉ mục được phân nhóm là chính bảng đó. (Nó không phải là bản sao của bảng, nó là bảng.) Các hàng của chỉ mục được sắp xếp hợp lý theo bất kỳ cột nào được xác định là khóa chỉ mục nhóm.
- Cấp độ lá của chỉ mục không phân biệt chứa một hàng chỉ mục cho mọi hàng trong bảng. Các hàng chứa các cột khóa không phân biệt và được sắp xếp hợp lý theo thứ tự các khóa được chỉ định. Ngoài các cột chính, các hàng chỉ mục không phân biệt chứa một 'dấu trang' trỏ đến hàng được tham chiếu trong bảng. Dấu trang có thể ở một trong hai dạng:
- Nếu bảng có chỉ mục được phân nhóm, thì dấu trang là khoá chỉ mục được phân nhóm. (Nếu khóa chỉ mục được phân nhóm là một phần của khóa chỉ mục không hợp nhất, thì nó sẽ không bị trùng lặp.)
- Nếu bảng là một đống, dấu trang là ID Hàng hoặc RID, chỉ định vị trí thực của hàng. Vị trí thường được chỉ định là FileNum:PageNum:RowNum .
Các công cụ riêng của SQL Server cung cấp nhiều cách để xem kế hoạch thực thi truy vấn mà trình tối ưu hóa đã quyết định sử dụng cho một truy vấn cụ thể. Với việc bổ sung Gói điều chỉnh tiêu điểm nhiệm vụ, bạn có thể nhận được nhiều thông tin hơn nữa về kế hoạch của mình.
Đoạn mã sau tạo bản sao của hai bảng trong AdventureWorks cơ sở dữ liệu (Tôi đang sử dụng AdventureWorks2016 , nhưng bạn có thể sử dụng phiên bản khác).
USE AdventureWorks2016;
GO
DROP TABLE IF EXISTS SalesHeader;
GO
SELECT *
INTO SalesHeader
FROM Sales.SalesOrderHeader;
GO
DROP TABLE IF EXISTS SalesDetail;
GO
SELECT * INTO SalesDetail
FROM Sales.SalesOrderDetail;
GO
Bây giờ, hãy thực hiện một truy vấn nối hai bảng với nhau, sau khi bật “Bao gồm kế hoạch thực thi thực tế”
SELECT h.SalesOrderID, OrderDate, ProductID, UnitPrice, OrderQty
FROM SalesHeader h JOIN SalesDetail d
ON h.SalesOrderID = d.SalesOrderID
WHERE SalesOrderDetailID < 100;
GO
Quest Spotlight Tuning Pack sẽ báo cáo sự cố với truy vấn, vì vậy bạn có thể nhấp vào “Xem phân tích” và chọn tùy chọn “Kế hoạch thực thi”. Bạn sẽ thấy như sau:
Hiểu cách quét bảng
Đầu tiên, tôi muốn đi ra ngoài và nói rằng không có nhà điều hành kế hoạch luôn luôn tồi tệ! Tại sao trình tối ưu hóa sẽ thêm nó vào kế hoạch truy vấn của bạn nếu nó kém? Nó có thể cho thấy có chỗ để cải thiện cấu trúc dữ liệu hoặc chỉ mục của bạn, nhưng bản thân nó không tệ.
Trong ví dụ trên, Gói điều chỉnh dường như đang làm nổi bật các bản quét bảng, cho thấy rằng chúng có thể có vấn đề. Nhưng không phải lúc nào việc quét bảng cũng có vấn đề. Một tình huống tồi tệ hơn nhiều sẽ là sử dụng tìm kiếm chỉ mục không phân biệt cho một truy vấn truy cập mọi hàng trong bảng. Đối với truy vấn cụ thể này, tôi đồng ý rằng việc quét có thể không phải là một điều tốt vì chúng tôi chỉ quan tâm đến một vài hàng trong SalesDetail bảng (99 trên 121.317 hàng, hoặc ít hơn một phần mười phần trăm.)
Vì vậy, chúng ta có thể xem các đề xuất trong ngăn Phân tích để xây dựng chỉ mục. Đề xuất cho Chi tiết bán hàng bảng là để tạo chỉ mục không phân bổ trên SalesOrderID (cột trong mệnh đề THAM GIA) và BAO GỒM mọi cột khác trong bảng được trả về bởi truy vấn. Đề xuất cho SalesHeader bảng là một chỉ mục không hợp nhất trên SalesOrderDetailId , là cột trong mệnh đề WHERE và BAO GỒM Ngày đặt hàng , là cột duy nhất khác được trả về từ bảng này.
Điều gì sẽ xảy ra nếu truy vấn của chúng tôi hơi khác? Điều gì sẽ xảy ra nếu tôi đã chạy truy vấn này bằng cách sử dụng SELECT * thay vì một danh sách cột cụ thể. Nếu bạn dùng thử và xem các đề xuất, bạn nên sử dụng INCLUDE cho mọi cột trong bảng ngoài cột khóa đơn. Mặc dù chỉ mục như vậy có thể làm cho truy vấn cụ thể này chạy nhanh hơn một chút, nhưng nó có thể làm chậm các truy vấn khác, cụ thể là các truy vấn CẬP NHẬT của bạn. Chỉ mục này về cơ bản chỉ là một bản sao của bảng, vì cấp độ lá của chỉ mục sẽ chứa mọi cột đơn trong bảng. Nếu bạn thấy các đề xuất như thế này, đề xuất một chỉ mục bao gồm tất cả các cột trong bảng, tôi chắc chắn khuyên bạn nên lùi lại một chút và không tạo nó một cách mù quáng.
Điều chỉnh truy vấn cho chẩn đoán máy chủ SQL của bạn không chỉ liên quan đến việc quản lý các chỉ mục mà còn quản lý chính các truy vấn. Đối với truy vấn cụ thể này, chúng tôi thực sự có thể viết lại truy vấn để KHÔNG sử dụng SELECT * để trả về mọi hàng trong bảng. Chỉ trả lại một tập hợp con nhỏ của các cột có thể là đủ, và sau đó chỉ mục hẹp hơn nhiều sẽ đủ, như trong ví dụ đầu tiên.
Liệu một trong hai chỉ mục này có thực sự là một chỉ mục tốt để tạo không? Chỉ số hẹp hơn sẽ nhỏ hơn về tổng thể và sẽ ít bị ảnh hưởng bởi các bản cập nhật dữ liệu. Một chỉ mục trên tất cả các cột giống như một bản sao thứ hai của bảng, được sắp xếp theo một thứ tự khác với chính bảng đó. Có những tình huống mà việc có một "bản sao thứ hai" của bảng theo một thứ tự khác có thể hữu ích, nhưng sẽ có rất nhiều chi phí cho các hoạt động sửa đổi dữ liệu. Cách duy nhất để biết chắc chắn là thử các đề xuất trên hệ thống thử nghiệm với khối lượng công việc đại diện. Chỉ bạn mới biết dữ liệu và truy vấn của bạn, vì vậy hãy thử và xem!
Hiểu các bản quét chỉ mục
Như tôi đã đề cập ở trên, quét bảng không phải lúc nào cũng là một điều xấu. Nhưng những gì về quét chỉ mục? Bởi vì mức lá chỉ mục nhóm là chính bảng, nên việc quét chỉ mục theo nhóm cũng giống như quét bảng! nếu quá trình quét bảng không tốt, quá trình quét chỉ mục theo cụm cũng tệ như vậy. Nhưng nó không phải lúc nào cũng xấu. Một lần nữa, bạn cần kiểm tra nó trên hệ thống của mình.
Các khuyến nghị từ SQL Server Engine mà Quest Spotlight Tuning Pack cho thấy bạn không bao giờ đề xuất một chỉ mục theo nhóm. nó có thể gợi ý một nonclustered bao gồm mọi cột trong bảng (như đã đề cập trước đó), chỉ là một bản sao của bảng. Việc tìm ra cột hoặc các cột tốt nhất cho chỉ mục nhóm của bạn là một chủ đề lớn, vì vậy, tôi sẽ không đi sâu vào vấn đề đó ở đây.
Tìm kiếm là gì? Hoạt động tìm kiếm trong một kế hoạch có nghĩa là SQL Server đang sử dụng dữ liệu có thứ tự trong cây chỉ mục để tìm một hàng, một tập hợp các hàng hoặc điểm bắt đầu và / hoặc điểm dừng trong một phạm vi hàng. Nói chung, sử dụng tìm kiếm chỉ mục không phân biệt là một hoạt động hoàn toàn hợp lý nếu bạn chỉ trả về một tỷ lệ rất nhỏ các hàng từ một bảng. Nhưng một tìm kiếm không phải là một lựa chọn tốt cho một truy vấn đang trả về RẤT NHIỀU hàng từ một bảng. Bao nhiêu là rất nhiều? Không có câu trả lời đơn giản nhưng nếu truy vấn của bạn trả về nhiều hơn một vài phần trăm số hàng, bạn nên đảm bảo rằng bạn đã kiểm tra kỹ lưỡng các đề xuất chỉ mục. Đôi khi, quét bảng, hoặc quét chỉ mục theo cụm, tốt hơn là tìm kiếm chỉ mục. (Để biết một ví dụ như vậy, hãy xem bài đăng trên blog của tôi tại đây).
Các công cụ như Gói điều chỉnh tiêu điểm nhiệm vụ có thể cung cấp cho bạn các đề xuất tuyệt vời để bắt đầu hành trình điều chỉnh với chẩn đoán máy chủ SQL, nhưng bạn càng biết nhiều về cách hoạt động của chỉ mục SQL Server và trình tối ưu hóa SQL Server, bạn càng có thể đánh giá các đề xuất đó cho các truy vấn của mình và dữ liệu và thậm chí có thể đưa ra các đề xuất của riêng bạn.
Trong các bài đăng sau trong loạt bài này, tôi sẽ cho bạn biết về các toán tử có vấn đề khác có thể hiển thị trong kế hoạch truy vấn của bạn, vì vậy hãy kiểm tra lại sớm!