Ước tính Cardinality cho> = và> cho giá trị thống kê trong bước


9

Tôi đang cố gắng hiểu cách SQL Server cố gắng ước tính cho 'lớn hơn' và 'lớn hơn bằng' trong các mệnh đề trong SQL Server 2014.

Tôi nghĩ rằng tôi hiểu được ước tính cardinality khi nó đạt được bước chẳng hạn nếu tôi làm

    select * from charge where charge_dt >= '1999-10-13 10:47:38.550'

Ước tính cardinality là 6672, có thể dễ dàng tính được là 32 (EQ_lawS) + 6624 (RANGE_lawS) + 16 (EQ_lawS) = 6672 (biểu đồ trong ảnh chụp màn hình bên dưới)

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

Nhưng khi tôi làm

    select * from charge where charge_dt >= '1999-10-13 10:48:38.550' 

(tăng thời gian lên 10:48 vì vậy đây không phải là một bước)

ước tính là 4844,13.

Nó được tính như thế nào?

Câu trả lời:


9

Khó khăn duy nhất là trong việc quyết định cách xử lý (các) bước biểu đồ được bao phủ một phần bởi khoảng vị ngữ truy vấn. Toàn bộ các bước biểu đồ được bao phủ bởi phạm vi vị ngữ là không đáng kể như đã lưu ý trong câu hỏi.

Công cụ ước tính Cardinality kế thừa

F = phân số (từ 0 đến 1) của phạm vi bước được bao phủ bởi vị từ truy vấn.

Ý tưởng cơ bản là sử dụng F(nội suy tuyến tính) để xác định có bao nhiêu giá trị riêng biệt trong bước được bao phủ bởi vị từ. Nhân kết quả này với số hàng trung bình trên mỗi giá trị riêng biệt (giả sử tính đồng nhất) và thêm bước hàng bằng nhau sẽ cho ước tính số lượng thẻ:

Cardinality = EQ_lawS + (AVG_RANGE_lawS * F * DISTINCT_RANGE_lawS)

Công thức tương tự được sử dụng cho >>=trong di sản CE.

Công cụ ước tính Cardinality mới

CE mới sửa đổi thuật toán trước một chút để phân biệt giữa >>=.

Lấy >đầu tiên, công thức là:

Cardinality = EQ_lawS + (AVG_RANGE_lawS * (F * (DISTINCT_RANGE_lawS - 1)))

Đối với >=nó là:

Cardinality = EQ_lawS + (AVG_RANGE_lawS * ((F * (DISTINCT_RANGE_lawS - 1)) + 1))

Phản + 1ánh rằng khi so sánh liên quan đến sự bình đẳng, một trận đấu được giả định (giả định bao gồm).

Trong ví dụ câu hỏi, Fcó thể được tính như sau:

DECLARE 
    @Q datetime = '1999-10-13T10:48:38.550',
    @K1 datetime = '1999-10-13T10:47:38.550',
    @K2 datetime = '1999-10-13T10:51:19.317';

DECLARE
    @QR float = DATEDIFF(MILLISECOND, @Q, @K2), -- predicate range
    @SR float = DATEDIFF(MILLISECOND, @K1, @K2) -- whole step range

SELECT
    F = @QR / @SR;

Kết quả là 0,728219019233034 . Cắm nó vào công thức cho >=các giá trị đã biết khác:

Cardinality = EQ_lawS + (AVG_RANGE_lawS * ((F * (DISTINCT_RANGE_lawS - 1)) + 1))
            = 16 + (16.1956 * ((0.728219019233034 * (409 - 1)) + 1))
            = 16 + (16.1956 * ((0.728219019233034 * 408) + 1))
            = 16 + (16.1956 * (297.113359847077872 + 1))
            = 16 + (16.1956 * 298.113359847077872)
            = 16 + 4828.1247307393343837632
            = 4844.1247307393343837632
            = 4844.12473073933 (để chính xác nổi)

Kết quả này phù hợp với ước tính 4844,13 được hiển thị trong câu hỏi.

Truy vấn tương tự bằng cách sử dụng CE kế thừa (ví dụ: sử dụng cờ theo dõi 9481) sẽ tạo ra ước tính:

Cardinality = EQ_lawS + (AVG_RANGE_lawS * F * DISTINCT_RANGE_lawS)
            = 16 + (16.1956 * 0.728219019233034 * 409)
            = 16 + 4823.72307468722
            = 4839,72307468722

Lưu ý rằng ước tính sẽ giống nhau >>=sử dụng CE kế thừa.


4

Công thức để ước tính các hàng trở nên hơi ngớ ngẩn khi bộ lọc "lớn hơn" hoặc "nhỏ hơn", nhưng đó là một số bạn có thể đến.

Những con số

Sử dụng bước 193, đây là những con số liên quan:

RANGE_lawS = 6624

EQ_lawS = 16

AVG_RANGE_lawS = 16.1956

RANGE_HI_KEY từ bước trước = 1999-10-13 10: 47: 38.550

RANGE_HI_KEY từ bước hiện tại = 1999-10-13 10: 51: 19.317

Giá trị từ mệnh đề WHERE = 1999-10-13 10: 48: 38.550

Công thức

1) Tìm ms giữa hai phím hi

SELECT DATEDIFF (ms, '1999-10-13 10:47:38.550', '1999-10-13 10:51:19.317')

Kết quả là 220767 ms.

2) Điều chỉnh số lượng hàng

Chúng tôi cần tìm các hàng mỗi mili giây, nhưng trước khi thực hiện, chúng tôi phải trừ AVG_RANGE_lawS khỏi RANGE_lawS:

6624 - 16.1956 = 6607.8044 hàng

3) Tính toán các hàng trên ms với số lượng hàng được điều chỉnh:

6607.8044 hàng / 220767 ms = .0299311 hàng mỗi ms

4) Tính ms giữa giá trị từ mệnh đề WHERE và bước hiện tại RANGE_HI_KEY

SELECT DATEDIFF (ms, '1999-10-13 10:48:38.550', '1999-10-13 10:51:19.317')

Điều này mang lại cho chúng tôi 160767 ms.

5) Tính toán các hàng trong bước này dựa trên các hàng mỗi giây:

.0299311 hàng / ms * 160767 ms = 4811.932 hàng

6) Hãy nhớ cách chúng tôi đã trừ AVG_RANGE_lawS trước đó? Thời gian để thêm chúng trở lại. Bây giờ chúng ta đã hoàn thành việc tính toán các số liên quan đến hàng mỗi giây, chúng ta cũng có thể thêm EQ_lawS một cách an toàn:

4811.932 + 16.1956 + 16 = 4844.1288

Làm tròn lên, đó là ước tính 4844,13 của chúng tôi.

Kiểm tra công thức

Tôi không thể tìm thấy bất kỳ bài viết hoặc bài đăng trên blog nào về lý do tại sao AVG_RANGE_lawS bị trừ đi trước khi các hàng trên mỗi ms được tính toán. Tôi đã có thể xác nhận chúng được tính toán trong ước tính, nhưng chỉ ở mili giây cuối cùng - theo nghĩa đen.

Sử dụng cơ sở dữ liệu WideWorldImporters , tôi đã thực hiện một số thử nghiệm gia tăng và thấy việc giảm ước tính hàng là tuyến tính cho đến cuối bước, trong đó 1x AVG_RANGE_lawS đột nhiên được tính.

Đây là truy vấn mẫu của tôi:

SELECT PickingCompletedWhen
FROM Sales.Orders
WHERE PickingCompletedWhen >= '2016-05-24 11:00:01.000000'

Tôi đã cập nhật số liệu thống kê cho PickingCompletedWhen, sau đó nhận được biểu đồ:

DBCC SHOW_STATISTICS([sales.orders], '_WA_Sys_0000000E_44CA3770')

Biểu đồ cho _WA_Sys_0000000E_44CA3770 (3 bước cuối cùng)

Để xem các hàng ước tính giảm như thế nào khi chúng tôi tiếp cận RANGE_HI_KEY, tôi đã thu thập các mẫu trong suốt bước. Mức giảm là tuyến tính, nhưng hoạt động như thể một số hàng bằng với giá trị AVG_RANGE_lawS không phải là một phần của xu hướng ... cho đến khi bạn nhấn RANGE_HI_KEY và đột nhiên chúng giảm xuống như một khoản nợ không bị xóa. Bạn có thể thấy nó trong dữ liệu mẫu, đặc biệt là trong biểu đồ.

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

Lưu ý sự sụt giảm đều đặn trong các hàng cho đến khi chúng tôi đạt RANGE_HI_KEY và sau đó BOOM mà đoạn AVG_RANGE_lawS cuối cùng bị trừ đột ngột. Thật dễ dàng để nhận ra trong một biểu đồ, quá.

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

Tóm lại, cách xử lý kỳ quặc của AVG_RANGE_lawS làm cho việc tính toán các ước tính hàng phức tạp hơn, nhưng bạn luôn có thể điều hòa những gì CE đang làm.

Điều gì về Backoffential Backoff?

Backoffential Backoff là phương pháp mà Công cụ ước tính Cardinality mới (kể từ SQL Server 2014) sử dụng để có được ước tính tốt hơn khi sử dụng nhiều số liệu thống kê cột đơn. Vì câu hỏi này là về một chỉ số một cột, nên nó không liên quan đến công thức EB.

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.