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

Tạo một tập hợp hoặc trình tự không có vòng lặp - phần 2

Trong bài trước của tôi, tôi đã nói về các cách tạo một dãy số liền nhau từ 1 đến 1.000. Bây giờ tôi muốn nói về các cấp độ tiếp theo của quy mô:tạo ra các bộ số 50.000 và 1.000.000.

Tạo bộ 50.000 số

Khi bắt đầu loạt bài này, tôi thực sự tò mò làm thế nào các phương pháp tiếp cận khác nhau sẽ mở rộng quy mô thành các bộ số lớn hơn. Cuối cùng, tôi hơi mất hứng khi thấy rằng cách tiếp cận yêu thích của tôi - sử dụng sys.all_objects - không phải là phương pháp hiệu quả nhất. Nhưng các kỹ thuật khác nhau này sẽ mở rộng quy mô thành 50.000 hàng như thế nào?

    Bảng số

    Vì chúng tôi đã tạo một bảng Numbers với 1.000.000 hàng, nên truy vấn này hầu như giống hệt nhau:

     CHỌN ĐẦU (50000) n TỪ Dbo. SỐ LỆNH THEO n; 

    Kế hoạch:

    spt_values ​​

    Vì chỉ có ~ 2.500 hàng trong spt_values , chúng ta cần phải sáng tạo hơn một chút nếu muốn sử dụng nó làm nguồn của bộ tạo bộ của chúng ta. Một cách để mô phỏng một bảng lớn hơn là CROSS JOIN nó chống lại chính nó. Nếu chúng tôi làm điều đó thô, chúng tôi sẽ kết thúc với ~ 2.500 hàng bình phương (hơn 6 triệu). Chỉ cần 50.000 hàng, chúng ta cần khoảng 224 hàng bình phương. Vì vậy, chúng tôi có thể làm điều này:

    ; WITH x AS (SELECT TOP (224) number FROM [master] .. spt_values) SELECT TOP (50000) n =ROW_NUMBER () OVER (ORDER BY x.number) FROM x CROSS JOIN x AS yORDER BY n; 

    Lưu ý rằng điều này tương đương với, nhưng ngắn gọn hơn, biến thể này:

     SELECT TOP (50000) n =ROW_NUMBER () OVER (ORDER BY x.number) FROM (CHỌN HÀNG ĐẦU (224) số FROM [master] .. spt_values) AS xCROSS JOIN (CHỌN ĐẦU (224) số FROM [master ] .. spt_values) NHƯ YORDER BY n; 

    Trong cả hai trường hợp, kế hoạch trông như thế này:

    sys.all_objects

    Giống như spt_values , sys.all_objects không hoàn toàn đáp ứng yêu cầu 50.000 hàng của riêng chúng tôi, vì vậy chúng tôi sẽ cần thực hiện một CROSS JOIN tương tự .

    ;; WITH x AS (SELECT TOP (224) [object_id] FROM sys.all_objects) SELECT TOP (50000) n =ROW_NUMBER () OVER (ORDER BY x. [object_id]) FROM x CROSS JOIN x AS y ORDER THEO n; 

    Kế hoạch:

    CTE xếp chồng

    Chúng tôi chỉ cần thực hiện một điều chỉnh nhỏ đối với CTE xếp chồng của mình để có được chính xác 50.000 hàng:

    ; WITH e1 (n) AS (CHỌN 1 ĐOÀN TẤT CẢ CHỌN 1 ĐOÀN TẤT CẢ CHỌN 1 ĐOÀN TẤT CẢ CHỌN 1 ĐOÀN THỂ TẤT CẢ CHỌN 1 ĐOÀN TẤT CẢ CHỌN 1 ĐOÀN THỂ TẤT CẢ CHỌN 1 ĐOÀN THỂ TẤT CẢ CHỌN 1 ĐOÀN THỂ TẤT CẢ CHỌN 1 ĐOÀN THỂ TẤT CẢ CHỌN 1) , - 10e2 (n) AS (CHỌN 1 TỪ e1 CROSS JOIN e1 AS b), - 10 * 10e3 (n) AS (CHỌN 1 TỪ e2 CROSS JOIN e2 AS b), - 100 * 100e4 (n) AS (CHỌN 1 TỪ e3 THAM GIA CHÉO (CHỌN ĐẦU 5 n TỪ e1) NHƯ b) - 5 * 10000 CHỌN n =ROW_NUMBER () HẾT (LỆNH THEO n) TỪ e4 LỆNH THEO n; 

    Kế hoạch:

    CTE đệ quy

    Cần có một thay đổi ít quan trọng hơn nữa để có được 50.000 hàng từ CTE đệ quy của chúng tôi:thay đổi WHERE mệnh đề thành 50.000 và thay đổi MAXRECURSION tùy chọn về 0.

    ; WITH n (n) AS (CHỌN 1 ĐOÀN KẾT TẤT CẢ CHỌN n + 1 TỪ n TRONG ĐÓ n <50000) CHỌN n TỪ n ĐƠN HÀNG THEO nOPTION (MAXRECURSION 0); 

    Kế hoạch:

    Trong trường hợp này, có một biểu tượng cảnh báo về loại - hóa ra, trên hệ thống của tôi, loại cần thiết để tràn sang tempdb. Bạn có thể không thấy sự cố tràn trên hệ thống của mình, nhưng đây phải là một cảnh báo về các tài nguyên cần thiết cho kỹ thuật này.

    Hiệu suất

    Như với bộ thử nghiệm cuối cùng, chúng tôi sẽ so sánh từng kỹ thuật, bao gồm bảng Numbers với cả bộ đệm lạnh và bộ nhớ cache ấm và cả được nén và không nén:


    Thời gian chạy, tính bằng mili giây, để tạo 50.000 số liền kề

    Để có hình ảnh tốt hơn, hãy loại bỏ CTE đệ quy, là một con chó hoàn toàn trong thử nghiệm này và làm sai lệch kết quả:


    Thời gian chạy, tính bằng mili giây, để tạo 50.000 số liền kề (không bao gồm đệ quy CTE)

    Ở 1.000 hàng, sự khác biệt giữa được nén và không được nén là rất nhỏ, vì truy vấn chỉ cần đọc 8 và 9 trang tương ứng. Ở 50.000 hàng, khoảng cách rộng hơn một chút:74 trang so với 113. Tuy nhiên, chi phí tổng thể của việc giải nén dữ liệu dường như lớn hơn mức tiết kiệm trong I / O. Vì vậy, ở 50.000 hàng, một bảng số không nén có vẻ là phương pháp hiệu quả nhất để tính ra một tập liền kề - tuy nhiên, phải thừa nhận rằng lợi thế là không đáng kể.

Tạo bộ 1.000.000 số

Mặc dù tôi không thể hình dung ra nhiều trường hợp sử dụng mà bạn cần một bộ số liền nhau lớn như vậy, nhưng tôi muốn đưa nó vào cho hoàn chỉnh và bởi vì tôi đã thực hiện một số quan sát thú vị ở quy mô này.

    Bảng số

    Không có gì ngạc nhiên ở đây, truy vấn của chúng tôi bây giờ là:

     CHỌN HÀNG ĐẦU 1000000 n TỪ dbo. SỐ LỆNH THEO n; 

    TOP không hoàn toàn cần thiết, nhưng đó chỉ vì chúng ta biết rằng bảng Numbers và kết quả mong muốn của chúng ta có cùng số hàng. Kế hoạch vẫn khá giống với các thử nghiệm trước:

    spt_values ​​

    Để nhận CROSS JOIN tạo ra 1.000.000 hàng, chúng tôi cần lấy bình phương 1.000 hàng:

    ; WITH x AS (SELECT TOP (1000) number FROM [master] .. spt_values) SELECT n =ROW_NUMBER () OVER (ORDER BY x.number) FROM x CROSS JOIN x AS y ORDER BY n; 

    Kế hoạch:

    sys.all_objects

    Một lần nữa, chúng ta cần tích chéo của 1.000 hàng:

    ; WITH x AS (SELECT TOP (1000) [object_id] FROM sys.all_objects) SELECT n =ROW_NUMBER () OVER (ORDER BY x. [object_id]) FROM x CROSS JOIN x AS y ORDER BY n;  

    Kế hoạch:

    CTE xếp chồng

    Đối với CTE xếp chồng lên nhau, chúng ta chỉ cần kết hợp CROSS JOIN hơi khác một chút s để nhận được 1.000.000 hàng:

    ; WITH e1 (n) AS (CHỌN 1 ĐOÀN TẤT CẢ CHỌN 1 ĐOÀN TẤT CẢ CHỌN 1 ĐOÀN TẤT CẢ CHỌN 1 ĐOÀN THỂ TẤT CẢ CHỌN 1 ĐOÀN TẤT CẢ CHỌN 1 ĐOÀN THỂ TẤT CẢ CHỌN 1 ĐOÀN THỂ TẤT CẢ CHỌN 1 ĐOÀN THỂ TẤT CẢ CHỌN 1 ĐOÀN THỂ TẤT CẢ CHỌN 1) , - 10e2 (n) AS (CHỌN 1 TỪ e1 CROSS JOIN e1 AS b), - 10 * 10e3 (n) AS (CHỌN 1 TỪ e1 CROSS JOIN e2 AS b), - 10 * 100e4 (n) AS (CHỌN 1 TỪ e3 CHÉO THAM GIA e3 NHƯ b) - 1000 * 1000 CHỌN n =ROW_NUMBER () HẾT (LỆNH THEO n) TỪ e4 LỆNH THEO n; 

    Kế hoạch:

    Ở kích thước hàng này, bạn có thể thấy rằng giải pháp CTE xếp chồng song song với nhau. Vì vậy, tôi cũng đã chạy một phiên bản với MAXDOP 1 để có được hình dạng kế hoạch tương tự như trước đây và để xem liệu tính song song có thực sự hữu ích hay không:

    CTE đệ quy

    CTE đệ quy một lần nữa chỉ có một thay đổi nhỏ; chỉ WHERE mệnh đề cần thay đổi:

    ; WITH n (n) AS (CHỌN 1 ĐOÀN KẾT TẤT CẢ CHỌN n + 1 TỪ n TRONG ĐÓ n <1000000) CHỌN n TỪ n ĐƠN HÀNG THEO nOPTION (MAXRECURSION 0); 

    Kế hoạch:

    Hiệu suất

    Một lần nữa chúng ta thấy hiệu suất của CTE đệ quy rất kém:


    Thời gian chạy, tính bằng mili giây, để tạo 1.000.000 số liền kề

    Loại bỏ yếu tố ngoại lệ đó khỏi biểu đồ, chúng tôi sẽ có bức tranh tốt hơn về hiệu suất:


    Thời gian chạy, tính bằng mili giây, để tạo 1.000.000 số liền kề (không bao gồm đệ quy CTE)

    Mặc dù một lần nữa, chúng ta thấy bảng Numbers không nén (ít nhất là với bộ đệm ấm) là bảng chiến thắng, nhưng sự khác biệt ngay cả ở thang điểm này không phải là tất cả những gì đáng chú ý.

Còn tiếp…

Bây giờ chúng ta đã khám phá kỹ lưỡng một số phương pháp để tạo một chuỗi số, chúng ta sẽ chuyển sang ngày. Trong bài cuối cùng của loạt bài này, chúng ta sẽ xem xét việc xây dựng phạm vi ngày dưới dạng một tập hợp, bao gồm việc sử dụng bảng lịch và một số trường hợp sử dụng mà việc này có thể hữu ích.

[Phần 1 | Phần 2 | Phần 3]

Phụ lục:Số hàng

Bạn có thể không cố gắng tạo ra một số hàng chính xác; thay vào đó, bạn có thể chỉ muốn một cách đơn giản để tạo ra nhiều hàng. Sau đây là danh sách kết hợp các chế độ xem danh mục sẽ giúp bạn có được các số lượng hàng khác nhau nếu bạn chỉ cần SELECT không có WHERE mệnh đề. Lưu ý rằng những con số này sẽ phụ thuộc vào việc bạn đang sử dụng RTM hay gói dịch vụ (vì một số đối tượng hệ thống được thêm vào hoặc sửa đổi) và cả việc bạn có cơ sở dữ liệu trống không.

Nguồn Số lượng hàng
SQL Server 2008 R2 SQL Server 2012 SQL Server 2014
master..spt_values ​​

2.508

2,515 2,519
master..spt_values ​​CROSS JOIN master..spt_values ​​

6.290.064

6.325.225 6.345.361
sys.all_objects

1.990

2.089 2.165
sys.all_columns

5,157

7.276 8.560
sys.all_objects CROSS THAM GIA sys.all_objects

3.960.100

4.363.921 4.687.225
sys.all_objects CROSS THAM GIA sys.all_columns

10.262.430

15.199.564 18.532.400
sys.all_columns CROSS THAM GIA sys.all_columns

26.594.649

52,940,176 73.273.600

Bảng 1:Số hàng cho các truy vấn xem danh mục khác nhau


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Đọc cách ly ảnh chụp nhanh đã cam kết

  2. Tùy chọn cơ sở dữ liệu / Báo cáo sử dụng gói

  3. Beverly Hills 90210 và ZIP + 4:Xử lý địa chỉ trong mô hình dữ liệu

  4. BẢNG ALTER SQL cho người mới bắt đầu

  5. Theo dõi cập nhật thống kê đồng bộ