Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Cái nhìn đầu tiên về Công cụ ước tính bản số của máy chủ SQL mới

Benjamin Nevarez là một nhà tư vấn độc lập có trụ sở tại Los Angeles, California, người chuyên về điều chỉnh và tối ưu hóa truy vấn SQL Server. Anh ấy là tác giả của “Điều chỉnh &Tối ưu hóa Truy vấn SQL Server 2014” và “Bên trong Trình Tối ưu hóa Truy vấn SQL Server” và là đồng tác giả của “Nội bộ SQL Server 2012”. Với hơn 20 năm kinh nghiệm trong lĩnh vực cơ sở dữ liệu quan hệ, Benjamin cũng đã từng là diễn giả tại nhiều hội nghị SQL Server, bao gồm PASS Summit, SQL Server Connections và SQLBits. Có thể tìm thấy blog của Benjamin tại http://www.benjaminnevarez.com và bạn cũng có thể liên hệ với anh ấy bằng e-mail qua địa chỉ quản trị viên tại benjaminnevarez dot com và trên twitter tại @BenjaminNevarez.

Mặc dù hầu hết thông tin, blog và tài liệu về SQL Server 2014 đều tập trung vào Hekaton và các tính năng mới khác, nhưng không có nhiều thông tin chi tiết được cung cấp về công cụ ước tính cardinality mới. Hiện tại BOL chỉ gián tiếp nói về nó trên phần Có gì mới (Công cụ cơ sở dữ liệu), nói rằng SQL Server 2014 “bao gồm những cải tiến đáng kể đối với thành phần tạo và tối ưu hóa kế hoạch truy vấn” và ALTER DATABASE cho biết cách bật hoặc tắt hành vi của nó. May mắn thay, chúng ta có thể có thêm một số thông tin bằng cách đọc tài liệu nghiên cứu Kiểm tra các mô hình ước tính bản số trong SQL Server của Campbell Fraser et al. Mặc dù trọng tâm của bài báo là quy trình đảm bảo chất lượng của mô hình ước tính mới, nhưng nó cũng cung cấp phần giới thiệu cơ bản về công cụ ước tính bản số mới và động lực của việc thiết kế lại nó.

Vì vậy, một công cụ ước tính cardinality là gì? Bộ ước lượng bản số là thành phần của bộ xử lý truy vấn có công việc là ước tính số hàng được trả về bởi các phép toán quan hệ trong một truy vấn. Thông tin này, cùng với một số dữ liệu khác, được sử dụng bởi trình tối ưu hóa truy vấn để chọn một kế hoạch thực thi hiệu quả. Ước tính bản số vốn dĩ không chính xác, vì nó là một mô hình toán học dựa trên thông tin thống kê. Nó cũng dựa trên một số giả định, mặc dù không được ghi lại, đã được biết đến trong nhiều năm - một số trong số đó bao gồm các giả định về tính đồng nhất, độc lập, ngăn chặn và bao hàm. Sau đây là mô tả ngắn gọn về những giả định này.

  1. Tính đồng nhất . Được sử dụng khi phân phối cho một thuộc tính không xác định, chẳng hạn như bên trong các hàng phạm vi trong một bước biểu đồ hoặc khi không có biểu đồ.
  2. Độc lập . Được sử dụng khi các thuộc tính trong một mối quan hệ là độc lập, trừ khi biết mối tương quan giữa chúng.
  3. Ngăn chặn . Được sử dụng khi hai thuộc tính có thể giống nhau, chúng được coi là giống nhau.
  4. Bao gồm . Được sử dụng khi so sánh một thuộc tính với một hằng số, nó được cho là luôn có một sự trùng khớp.

Thật thú vị là gần đây tôi đã nói về một số hạn chế của những giả định này trong buổi nói chuyện cuối cùng của tôi tại Hội nghị thượng đỉnh PASS, được gọi là Đánh bại các giới hạn của Trình tối ưu hóa truy vấn. Tuy nhiên, tôi rất ngạc nhiên khi đọc trong bài báo rằng các tác giả thừa nhận rằng, theo kinh nghiệm thực tế của họ, những giả định này “thường không chính xác”.

Công cụ ước tính bản số hiện tại được viết cùng với toàn bộ bộ xử lý truy vấn cho SQL Server 7.0, được phát hành vào tháng 12 năm 1998. Rõ ràng thành phần này đã phải đối mặt với nhiều thay đổi trong vài năm và nhiều bản phát hành của SQL Server, bao gồm các bản sửa lỗi, điều chỉnh và phần mở rộng cho phù hợp với ước tính số lượng cho các tính năng T-SQL mới. Vì vậy, bạn có thể đang nghĩ, tại sao lại thay thế một thành phần đã được sử dụng thành công trong khoảng 15 năm?

Tại sao lại sử dụng Công cụ ước tính số lượng mới

Bài báo giải thích một số lý do của việc thiết kế lại bao gồm:

  1. Để điều chỉnh công cụ ước tính bản số với các mẫu khối lượng công việc mới.
  2. Những thay đổi được thực hiện đối với công cụ ước tính bản số trong những năm qua khiến thành phần này khó "gỡ lỗi, dự đoán và hiểu".
  3. Việc cố gắng cải thiện mô hình hiện tại là khó khăn khi sử dụng kiến ​​trúc hiện tại, vì vậy, một thiết kế mới đã được tạo ra, tập trung vào việc tách biệt các nhiệm vụ của (a) quyết định cách tính toán một ước tính cụ thể và (b) thực sự thực hiện tính toán .

Tôi không chắc liệu có thêm thông tin chi tiết về công cụ ước tính cardinality mới sẽ được Microsoft xuất bản hay không. Rốt cuộc, không có quá nhiều chi tiết được công bố về công cụ ước tính hồng y cũ trong 15 năm; ví dụ, cách tính một số ước tính bản số cụ thể. Mặt khác, có những sự kiện mở rộng mới mà chúng ta có thể sử dụng để khắc phục sự cố với ước lượng bản số hoặc chỉ để khám phá cách nó hoạt động. Các sự kiện này bao gồm query_optimizer_estimate_cardinality , inaccurate_cardinality_estimate , query_optimizer_force_both_cardinality_estimation_behaviorsquery_rpc_set_cardinality .

Hồi quy kế hoạch

Một mối quan tâm chính xuất hiện trong tâm trí với một sự thay đổi lớn như vậy bên trong trình tối ưu hóa truy vấn là hồi quy kế hoạch. Nỗi sợ hãi về việc hồi quy kế hoạch đã được coi là trở ngại lớn nhất đối với các cải tiến của trình tối ưu hóa truy vấn. Hồi quy là các vấn đề được đưa ra sau khi áp dụng bản sửa lỗi cho trình tối ưu hóa truy vấn và đôi khi được gọi là "hai sai tạo thành một đúng". Điều này có thể xảy ra khi hai ước tính sai, ví dụ một ước tính quá cao một giá trị và ước tính thứ hai đánh giá thấp giá trị đó, loại bỏ nhau, may mắn là đưa ra ước tính tốt. Hiện chỉ sửa một trong các giá trị này có thể dẫn đến một ước tính không tốt, có thể tác động tiêu cực đến việc lựa chọn phương án, gây ra hồi quy.

Để giúp tránh hồi quy liên quan đến công cụ ước tính bản số mới, SQL Server cung cấp một cách để bật hoặc tắt nó, vì nó phụ thuộc vào mức độ tương thích của cơ sở dữ liệu. Điều này có thể được thay đổi bằng cách sử dụng ALTER DATABASE tuyên bố, như đã chỉ ra trước đó. Việc đặt cơ sở dữ liệu ở mức tương thích 120 sẽ sử dụng công cụ ước lượng bản số mới, trong khi mức tương thích nhỏ hơn 120 sẽ sử dụng công cụ ước tính bản số cũ. Ngoài ra, sau khi bạn đang sử dụng một công cụ ước tính bản số cụ thể, có hai cờ theo dõi bạn có thể sử dụng để thay đổi sang cờ kia. Mặc dù hiện tại tôi không thấy các cờ theo dõi được ghi lại ở bất kỳ đâu, nhưng chúng được đề cập như một phần của mô tả của query_optimizer_force_both_cardinality_estimation_behaviors sự kiện mở rộng. Cờ theo dõi 2312 có thể được sử dụng để kích hoạt công cụ ước lượng bản số mới, trong khi cờ theo dõi 9481 có thể được sử dụng để vô hiệu hóa nó. Bạn thậm chí có thể sử dụng các cờ theo dõi cho một truy vấn cụ thể bằng cách sử dụng QUERYTRACEON gợi ý (mặc dù nó vẫn chưa được ghi lại liệu điều này có được hỗ trợ hay không).

Ví dụ

Cuối cùng, bài báo cũng đề cập đến một số tình huống đã được thử nghiệm như khóa chính quá dân số, phép nối đơn giản hoặc vấn đề khóa tăng dần. Nó cũng cho thấy cách các tác giả đã thử nghiệm với nhiều kịch bản (hoặc các biến thể của mô hình) và trong một số trường hợp "nới lỏng" một số giả định được đưa ra bởi công cụ ước lượng bản số, ví dụ, trong trường hợp giả định về tính độc lập, đi từ độc lập hoàn toàn đến tương quan hoàn toàn. và một cái gì đó ở giữa cho đến khi tìm thấy kết quả tốt.

Mặc dù không có chi tiết nào được cung cấp trên bài báo, tôi quyết định bắt đầu thử nghiệm một số tình huống này để cố gắng hiểu cách hoạt động của công cụ ước tính bản số mới. Bây giờ tôi sẽ chỉ cho bạn ví dụ bằng cách sử dụng giả định độc lập và các khóa tăng dần. Tôi cũng đã thử nghiệm giả định về tính đồng nhất nhưng cho đến nay vẫn không thể tìm thấy bất kỳ sự khác biệt nào về ước tính.

Hãy bắt đầu với ví dụ giả định về tính độc lập. Đầu tiên chúng ta hãy xem hành vi hiện tại. Đối với điều đó, hãy đảm bảo rằng bạn đang sử dụng công cụ ước tính bản số cũ bằng cách chạy câu lệnh sau trên cơ sở dữ liệu AdventureWorks2012:

ALTER DATABASE AdventureWorks2012 SET COMPATIBILITY_LEVEL = 110;

Sau đó chạy:

SELECT * FROM Person.Address WHERE City = 'Burbank';

Chúng tôi nhận được ước tính khoảng 196 bản ghi như được hiển thị tiếp theo:

Theo cách tương tự, câu lệnh sau sẽ ước tính là 194:

SELECT * FROM Person.Address WHERE PostalCode = '91502';

Nếu chúng ta sử dụng cả hai vị từ, chúng ta có truy vấn sau, truy vấn này sẽ có số hàng ước tính là 1.93862 (làm tròn lên 2 hàng nếu sử dụng SQL Sentry Plan Explorer):

SELECT * FROM Person.Address WHERE City = 'Burbank' AND PostalCode = '91502';

Giá trị này được tính toán với giả định là hoàn toàn độc lập của cả hai vị từ, sử dụng công thức (196 * 194) / 19614.0 (trong đó 19614 là tổng số hàng trong bảng). Sử dụng tổng tương quan sẽ cho chúng tôi ước tính là 194, vì tất cả các bản ghi có mã bưu chính 91502 đều thuộc về Burbank. Công cụ ước tính số lượng mới ước tính một giá trị không giả định sự độc lập toàn bộ hoặc tổng tương quan. Thay đổi công cụ ước tính bản số mới bằng cách sử dụng câu lệnh sau:

ALTER DATABASE AdventureWorks2012 SET COMPATIBILITY_LEVEL = 120;
GO
 
SELECT * FROM Person.Address WHERE City = 'Burbank' AND PostalCode = '91502';

Chạy lại cùng một câu lệnh sẽ đưa ra ước tính là 19.3931 hàng, mà bạn có thể thấy là giá trị giữa giả định tổng mức độc lập và tổng tương quan (làm tròn đến 19 hàng trong Plan Explorer). Công thức được sử dụng là độ chọn lọc của bộ lọc chọn lọc nhất * SQRT (độ chọn lọc của bộ lọc chọn lọc tiếp theo) hoặc (194 / 19614.0) * SQRT (196 / 19614.0) * 19614 cho kết quả 19.393:

Nếu bạn đã bật công cụ ước tính bản số mới ở cấp cơ sở dữ liệu, muốn tắt nó cho một truy vấn cụ thể để tránh hồi quy kế hoạch, bạn có thể sử dụng cờ theo dõi 9481 như đã giải thích trước đó:

ALTER DATABASE AdventureWorks2012 SET COMPATIBILITY_LEVEL = 120;
GO
 
SELECT * FROM Person.Address WHERE City = 'Burbank' AND PostalCode = '91502'
  OPTION (QUERYTRACEON 9481);

Lưu ý:Gợi ý truy vấn QUERYTRACEON được sử dụng để áp dụng cờ theo dõi ở cấp truy vấn và hiện tại nó chỉ được hỗ trợ trong một số trường hợp hạn chế. Để biết thêm thông tin về gợi ý truy vấn QUERYTRACEON, bạn có thể xem tại http://support.microsoft.com/kb/2801413.

Bây giờ chúng ta hãy xem xét vấn đề chính tăng dần, một chủ đề mà tôi đã giải thích chi tiết hơn trong bài đăng này. Khuyến nghị truyền thống từ Microsoft để khắc phục sự cố này là cập nhật thủ công số liệu thống kê sau khi tải dữ liệu, như được giải thích ở đây - mô tả sự cố theo cách sau:

Thống kê trên các cột chính tăng dần hoặc giảm dần, chẳng hạn như IDENTITY hoặc cột dấu thời gian thời gian thực, có thể yêu cầu cập nhật thống kê thường xuyên hơn so với thực hiện của trình tối ưu hóa truy vấn. Các thao tác chèn nối các giá trị mới vào các cột tăng dần hoặc giảm dần. Số lượng hàng được thêm vào có thể quá ít để kích hoạt cập nhật thống kê. Nếu thống kê không được cập nhật và các truy vấn chọn từ các hàng được thêm gần đây nhất, thì thống kê hiện tại sẽ không có ước tính số lượng cho các giá trị mới này. Điều này có thể dẫn đến ước tính số lượng không chính xác và hiệu suất truy vấn chậm. Ví dụ:một truy vấn chọn từ các ngày đặt hàng bán hàng gần đây nhất sẽ có ước tính số lượng không chính xác nếu thống kê không được cập nhật để bao gồm các ước tính số lượng cho các ngày đặt hàng bán hàng gần đây nhất.

Khuyến nghị trong bài viết của tôi là sử dụng cờ theo dõi 2389 và 2390, được xuất bản lần đầu tiên bởi Ian Jose trong bài báo của anh ấy về Phím tăng dần và Thống kê sửa chữa nhanh tự động. Bạn có thể đọc bài viết của tôi để biết giải thích và ví dụ về cách sử dụng các cờ theo dõi này để tránh vấn đề này. Các cờ theo dõi này vẫn hoạt động trên SQL Server 2014 CTP2. Nhưng tốt hơn nữa, chúng không còn cần thiết nếu bạn đang sử dụng công cụ ước tính bản số mới.

Sử dụng cùng một ví dụ trong bài đăng của tôi:

CREATE TABLE dbo.SalesOrderHeader (
    SalesOrderID int NOT NULL,
    RevisionNumber tinyint NOT NULL,
    OrderDate datetime NOT NULL,
    DueDate datetime NOT NULL,
    ShipDate datetime NULL,
    Status tinyint NOT NULL,
    OnlineOrderFlag dbo.Flag NOT NULL,
    SalesOrderNumber nvarchar(25) NOT NULL,
    PurchaseOrderNumber dbo.OrderNumber NULL,
    AccountNumber dbo.AccountNumber NULL,
    CustomerID int NOT NULL,
    SalesPersonID int NULL,
    TerritoryID int NULL,
    BillToAddressID int NOT NULL,
    ShipToAddressID int NOT NULL,
    ShipMethodID int NOT NULL,
    CreditCardID int NULL,
    CreditCardApprovalCode varchar(15) NULL,
    CurrencyRateID int NULL,
    SubTotal money NOT NULL,
    TaxAmt money NOT NULL,
    Freight money NOT NULL,
    TotalDue money NOT NULL,
    Comment nvarchar(128) NULL,
    rowguid uniqueidentifier NOT NULL,
    ModifiedDate datetime NOT NULL
);

Chèn một số dữ liệu:

INSERT INTO dbo.SalesOrderHeader SELECT * FROM Sales.SalesOrderHeader 
WHERE OrderDate < '2008-07-20 00:00:00.000';
 
CREATE INDEX IX_OrderDate ON SalesOrderHeader(OrderDate);

Kể từ khi chúng tôi tạo một chỉ mục, chúng tôi chỉ có số liệu thống kê mới. Chạy truy vấn sau sẽ tạo ra một ước tính tốt là 35 hàng:

SELECT * FROM dbo.SalesOrderHeader WHERE OrderDate = '2008-07-19 00:00:00.000';

Nếu chúng tôi chèn dữ liệu mới:

INSERT INTO dbo.SalesOrderHeader SELECT * FROM Sales.SalesOrderHeader 
WHERE OrderDate = '2008-07-20 00:00:00.000';

Bạn có thể xem ước tính với công cụ ước tính bản số cũ như được hiển thị bên cạnh:

ALTER DATABASE AdventureWorks2012 SET COMPATIBILITY_LEVEL = 110;
GO
 
SELECT * FROM dbo.SalesOrderHeader WHERE OrderDate = '2008-07-20 00:00:00.000';

Vì số lượng nhỏ bản ghi được chèn vào không đủ để kích hoạt cập nhật tự động đối tượng thống kê, biểu đồ hiện tại không biết về các bản ghi mới được thêm vào và trình tối ưu hóa truy vấn sử dụng ước tính 1 hàng. Theo tùy chọn, bạn có thể sử dụng cờ theo dõi 2389 và 2390 để giúp ước tính tốt hơn. Nhưng nếu bạn thử cùng một truy vấn với công cụ ước tính bản số mới, bạn sẽ nhận được ước tính sau:

ALTER DATABASE AdventureWorks2012 SET COMPATIBILITY_LEVEL = 120;
GO
 
SELECT * FROM dbo.SalesOrderHeader WHERE OrderDate = '2008-07-20 00:00:00.000';

Trong trường hợp này, chúng tôi nhận được một ước tính tốt hơn so với công cụ ước tính cardinality cũ (hoặc chúng tôi nhận được ước tính tương tự như sử dụng cờ theo dõi 2389 hoặc 2390). Giá trị ước tính là 27,9631 (một lần nữa, được làm tròn thành 28 bởi Plan Explorer) được tính bằng cách sử dụng thông tin mật độ của đối tượng thống kê nhân với số hàng của bảng; nghĩa là, 0,0008992806 * 31095. Giá trị mật độ có thể được lấy bằng cách sử dụng:

DBCC SHOW_STATISTICS('dbo.SalesOrderHeader', 'IX_OrderDate');

Cuối cùng, hãy nhớ rằng không có gì được đề cập trong bài viết này được ghi lại và đây là hành vi mà tôi đã quan sát cho đến nay trong SQL Server 2014 CTP2. Bất kỳ điều nào trong số này có thể thay đổi trong CTP sau này hoặc phiên bản RTM của sản phẩm.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. 2 cách trả về tất cả các hàm do người dùng xác định trong cơ sở dữ liệu máy chủ SQL

  2. Tạo công việc tác nhân máy chủ SQL nhiều bước (T-SQL)

  3. Chuẩn bị một máy ảo mới cho SQL Server 2014 CTP1

  4. Cách sao lưu cơ sở dữ liệu SQL Server bằng T-SQL

  5. Chuỗi định dạng trong SQL Server là gì?