Trình tối ưu hóa của SQL Server ước tính số lượng hàng trong bảng đã tham gia như thế nào?


13

Tôi đang chạy truy vấn này trong AdventureWorks2012 cơ sở dữ liệu :

SELECT 
    s.SalesOrderID,
    d.CarrierTrackingNumber,
    d.ProductID,
    d.OrderQty
FROM Sales.SalesOrderHeader s 
JOIN Sales.SalesOrderDetail d 
    ON s.SalesOrderID = d.SalesOrderID
WHERE s.CustomerID = 11077

Nếu tôi nhìn vào kế hoạch thực hiện ước tính, tôi thấy như sau:

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

Tìm kiếm chỉ mục ban đầu (trên cùng bên phải) đang sử dụng chỉ mục IX_SalesOrderHeader_CustomerID và tìm kiếm trên chữ 11077. Nó có ước tính 2.6192 hàng.

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

Nếu tôi sử dụng DBCC SHOW_STATISTICS ('Sales.SalesOrderHeader', 'IX_SalesOrderHeader_CustomerID') WITH HISTOGRAM , nó cho thấy giá trị 11077 nằm giữa hai khóa được lấy mẫu 11019 và 11091.

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

Số lượng hàng trung bình khác nhau giữa 11019 và 11091 là 2.619718 hoặc được làm tròn thành 2.61972 là giá trị của các hàng ước tính được hiển thị cho tìm kiếm chỉ mục.

Phần tôi không hiểu là số lượng hàng ước tính cho chỉ mục được tìm kiếm trong bảng SalesOrderDetail.

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

Nếu tôi chạy DBCC SHOW_STATISTICS ('Sales.SalesOrderDetail', 'PK_SalesOrderDetail_SalesOrderID_SalesOrderDetailID'):

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

Vì vậy, mật độ của SalesOrderID (mà tôi đang tham gia) là 3.178134E-05. Điều đó có nghĩa là 1 / 3.178134E-05 (31465) bằng với số lượng giá trị SalesOrderID duy nhất trong bảng SalesOrderDetail.

Nếu có 31465 SalesOrderID duy nhất trong SalesOrderDetail, thì với phân phối chẵn, số lượng hàng trung bình trên mỗi SalesOrderID là 121317 (tổng số hàng) chia cho 31465. Trung bình là 3,85561

Vì vậy, nếu số lượng hàng ước tính được lặp qua là 2.61972 và trung bình được trả về trong 3.85561, tôi sẽ nghĩ rằng số lượng hàng ước tính sẽ là 2.61972 * 3.85561 = 10.10062.

Nhưng số lượng hàng ước tính là 11.4867.

Tôi nghĩ rằng sự hiểu biết của tôi về ước tính thứ hai là không chính xác và các con số khác nhau dường như chỉ ra điều đó. Tôi đang thiếu gì?

Câu trả lời:


20

Tôi nghĩ rằng sự hiểu biết của tôi về ước tính thứ hai là không chính xác và các con số khác nhau dường như chỉ ra điều đó. Tôi đang thiếu gì?

Sử dụng công cụ ước tính số lượng thẻ SQL Server 2012, tính chọn lọc của phép nối sẽ điều khiển số lượng hàng ước tính ở phía bên trong của các vòng lặp lồng nhau, chứ không phải theo cách khác.

Số 11.4867 được lấy (để hiển thị trong showplan) bằng cách chia số lượng ước tính tính toán của đầu ra tham gia (30,0919) cho số lần lặp (2.61972). Kết quả, sử dụng số học dấu phẩy động chính xác đơn, là 11.4867 .

Nó thực sự là đơn giản như vậy. Lưu ý rằng tính chọn lọc tham gia (logic) độc lập với sự lựa chọn của toán tử nối vật lý. Nó vẫn giống nhau cho dù việc tham gia cuối cùng được thực hiện bằng cách sử dụng toán tử vật lý Nested Loops, Hash hoặc Merge Join.

Trong SQL Server 2012 trở về trước, độ chọn lọc tham gia (nói chung) được ước tính bằng cách sử dụng SalesOrderIDbiểu đồ từ mỗi bảng (được tính cho từng bước của biểu đồ, sau khi căn chỉnh ranh giới bước sử dụng phép nội suy tuyến tính khi cần thiết). Các SalesOrderIDbiểu đồ kết hợp với các SalesOrderHeaderbảng cũng được điều chỉnh cho ảnh hưởng rộng của độc lập CustomerIDbộ lọc.

Điều đó không có nghĩa là có bất cứ điều gì "sai" về cơ bản với tính toán thay thế được đề xuất trong câu hỏi; nó chỉ tạo ra một loạt các giả định khác nhau. Sẽ luôn có nhiều cách khác nhau để tính toán hoặc kết hợp các ước tính cho một chuỗi các hoạt động logic nhất định. Không có gì đảm bảo chung rằng các phương pháp thống kê khác nhau được áp dụng cho cùng một dữ liệu sẽ tạo ra cùng một câu trả lời hoặc một phương pháp sẽ luôn vượt trội so với phương pháp khác. Sự không nhất quán do áp dụng các phương pháp thống kê khác nhau thậm chí có thể xuất hiện trong một kế hoạch thực hiện cuối cùng, mặc dù chúng hiếm khi được chú ý.

Là một lưu ý phụ, công cụ ước tính cardinality của SQL Server 2014 có cách tiếp cận khác để kết hợp thông tin biểu đồ được điều chỉnh theo bộ lọc độc lập ( "căn chỉnh thô" ), dẫn đến ước tính cuối cùng khác là 10.1006 hàng cho truy vấn này:

Plan for computation:

  CSelCalcExpressionComparedToExpression
  (QCOL: [s].SalesOrderID x_cmpEq QCOL: [d].SalesOrderID)

Loaded histogram for column QCOL: [s].SalesOrderID from stats with id 1
Loaded histogram for column QCOL: [d].SalesOrderID from stats with id 1

Stats collection generated: 

  CStCollJoin(ID=4, **CARD=10.1006** x_jtInner)
      CStCollFilter(ID=3, CARD=2.61972)
          CStCollBaseTable(ID=1, CARD=31465 TBL: Sales.SalesOrderHeader AS TBL: s)
      CStCollBaseTable(ID=2, CARD=121317 TBL: Sales.SalesOrderDetail AS TBL: d)

Điều này xảy ra là kết quả tương tự như tính toán trong câu hỏi, mặc dù lý do chi tiết là khác nhau (nghĩa là nó không dựa trên việc thực hiện các vòng lặp lồng nhau giả định).

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.