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

COUNT (rowid) có nhanh hơn COUNT (*) không?

Một cuộc thảo luận lâu đời trên các diễn đàn và nhóm tin Oracle là hiệu quả của việc sử dụng count (*) để trả về số lượng hàng từ một bảng nhất định. Một nếp nhăn mới trong cuộc thảo luận đó bây giờ giới thiệu số đếm (rowid) như một sự thay thế hiệu quả hơn; đối số nói rằng count (*) mở rộng toàn bộ danh sách cột, giống như “select *…”, và như vậy, có thể là phần chìm tài nguyên khi các cột CLOB có trong bảng mong muốn. Hãy xem lập luận đó và xem nó có giữ được nước không. Hãy bắt đầu bằng cách tạo và điền một bảng có chứa cột CLOB:

 SQL> SQL> tạo bảng count_test (2 id number, 3 val varchar2 (40), 4 clb clob); Đã tạo bảng.SQL> SQL> begin 2 for z in 1..1000000 loop 3 insert vào count_test 4 giá trị (z, 'Bản ghi' || z, 'Giá trị clob' || z); 5 vòng kết thúc; 6 7 cam kết; 8 cuối; 9 / Thủ tục PL / SQL đã được hoàn tất thành công.SQL> 

Tiếp theo, hãy thiết lập sự kiện 10053 để kết xuất dấu vết trình tối ưu hóa để chúng ta có thể thấy cách Oracle dự định thực hiện các truy vấn count ():

 SQL> thay đổi phiên thiết lập sự kiện ='10053 ngữ cảnh tên theo dõi vĩnh viễn, cấp 2'; Phiên đã thay đổi. 

Giai đoạn đã được thiết lập, hãy chạy một số biến thể của count () để xem Oracle hoạt động như thế nào. Đầu tiên, chúng tôi sẽ thực hiện một số đếm thẳng (*) và hiển thị kế hoạch:

 SQL> chọn count (*) từ count_test; COUNT (*) ---------- 1000000SQL> thay đổi phiên đặt sự kiện ='Tắt ngữ cảnh tên theo dõi 10053'; Phiên đã thay đổi.SQL> giải thích kế hoạch cho số lượng được chọn (*) từ count_test; Giải thích.SQL> chọn * từ bảng (dbms_xplan.display (null, null, 'chiếu')); PLAN_TABLE_OUTPUT ------------------------------- -------------------------------------------------- ------------------------- Giá trị băm của kế hoạch:371675025 -------------------- -------------------- + ----------------------------- ------ + | Id | Hoạt động | Tên | Hàng | Số byte | Chi phí | Thời gian | ---------------------------------------- + ------- ---------------------------- + | 0 | TUYỂN CHỌN BÁO CÁO | | | | 3582 | || 1 | SẮP XẾP TỔNG HỢP | | 1 | | | || 2 | BẢNG TRUY CẬP ĐẦY ĐỦ | COUNT_TEST | 848 nghìn | | 3582 | 00:00:43 | ---------------------------------------- + --- -------------------------------- + Thông tin chiếu cột (được xác định bằng id hoạt động):------- -------------------------------------------------- - 1 - (# khóa =0) COUNT (*) [22] 2 - (tập hàng =1019) Lưu ý ----- - thống kê động được sử dụng:lấy mẫu động (cấp =2) 19 hàng được chọn. QL>  

Nhìn vào tệp theo dõi được tạo ra Oracle chỉ cần sử dụng count (*) nguyên trạng để trả về kết quả:

 Truy vấn cuối cùng sau khi chuyển đổi:******* CÂU HỎI KHÔNG CHUẨN BỊ ******* CHỌN COUNT (*) "COUNT (*)" TỪ "BING". "COUNT_TEST" "COUNT_TEST" ... ----- Giải thích Kế hoạch Dump ---------- Bảng Kế hoạch ----- ============Bảng Kế hoạch ============---------------------------------------- + -------- --------------------------- + | Id | Hoạt động | Tên | Hàng | Số byte | Chi phí | Thời gian | ---------------------------------------- + ------- ---------------------------- + | 0 | TUYỂN CHỌN BÁO CÁO | | | | 3582 | || 1 | SẮP XẾP TỔNG HỢP | | 1 | | | || 2 | BẢNG TRUY CẬP ĐẦY ĐỦ | COUNT_TEST | 848 nghìn | | 3582 | 00:00:43 | ---------------------------------------- + --- -------------------------------- + Tên khối truy vấn / Bí danh đối tượng (được xác định bằng id hoạt động):---- -------------------------------------------------- ------ 1 - SEL $ 12 - SEL $ 1 / "COUNT_TEST" @ "SEL $ 1" ---------------------------- -------------------------------- Thông tin vị ngữ:--------------- --------- SQL> 

Không có gì ngạc nhiên ở đó; lưu ý rằng Oracle không mở rộng “*” cho tất cả các cột trong bảng - “*” trong trường hợp này chỉ ra rằng tất cả các hàng sẽ được đếm. Nếu một tên cột thực được cung cấp thì Oracle sẽ tính các giá trị trong cột được chỉ định. Bây giờ chúng ta hãy xem xét những gì Oracle làm với truy vấn đếm (rowid):

 SQL> thay đổi phiên đặt sự kiện ='10053 ngữ cảnh tên theo dõi vĩnh viễn, cấp 2'; Phiên đã thay đổi.SQL> chọn số lượng (rowid) từ count_test; COUNT (ROWID) ------------ 1000000SQL> thay đổi phiên đặt sự kiện ='Tắt ngữ cảnh tên theo dõi 10053'; Phiên đã thay đổi.SQL> giải thích kế hoạch cho số lượng được chọn (rowid) từ count_test; Giải thích.SQL> chọn * từ bảng (dbms_xplan.display (null, null, 'chiếu ')); PLAN_TABLE_OUTPUT -------------------------------------------------- -------------------------------------------------- ---- Giá trị băm của kế hoạch:371675025 ---------------------------------------- + ----------------------------------- + | Id | Hoạt động | Tên | Hàng | Số byte | Chi phí | Thời gian | ---------------------------------------- + ------- ---------------------------- + | 0 | TUYỂN CHỌN BÁO CÁO | | | | 3582 | || 1 | SẮP XẾP TỔNG HỢP | | 1 | 12 | | || 2 | BẢNG TRUY CẬP ĐẦY ĐỦ | COUNT_TEST | 848 nghìn | 9941K | 3582 | 00:00:43 | ---------------------------------------- + --- -------------------------------- + Thông tin chiếu cột (được xác định bằng id hoạt động):------- -------------------------------------------------- - 1 - (# khóa =0) COUNT (ROWID) [22] 2 - (tập hàng =256) ROWID [ROWID, 10] Lưu ý ----- - thống kê động được sử dụng:lấy mẫu động (cấp =2) 19 hàng đã chọn.SQL> 

Oracle tạo ra một giá trị rowid cho mỗi hàng trong bảng, một hoạt động sẽ tiêu tốn một số tài nguyên CPU. Vì truy vấn được trả về trong khoảng thời gian gần giống với phiên bản count (*) nên hiệu suất ‘lần truy cập’ dường như không đáng kể. Việc thêm khóa chính sẽ thay đổi một chút kế hoạch nhưng không thay đổi văn bản truy vấn:

 SQL> thay đổi bảng count_test thêm ràng buộc khóa chính count_pk (id); Bảng đã thay đổi. SQL> SQL> thay đổi phiên thiết lập sự kiện ='10053 bối cảnh tên theo dõi mãi mãi, cấp 2'; Phiên đã thay đổi.SQL> chọn số lượng (*) từ count_test; COUNT (*) ---------- 1000000SQL> thay đổi phiên đặt sự kiện ='Tắt ngữ cảnh tên theo dõi 10053'; Phiên đã thay đổi.SQL> giải thích kế hoạch cho số lượng được chọn (*) từ count_test; Giải thích.SQL> chọn * từ bảng (dbms_xplan.display (null, null, 'chiếu')); PLAN_TABLE_OUTPUT ------------------------------- -------------------------------------------------- --------------------- Giá trị băm của kế hoạch:371675025 ------------------------ -------------------------------------------------- | Id | Hoạt động | Tên | Hàng | Chi phí (% CPU) | Thời gian | ------------------------------------------------ -------------------------- | 0 | TUYỂN CHỌN BÁO CÁO | | 1 | 589 (2) | 00:00:01 || 1 | SẮP XẾP TỔNG HỢP | | 1 | | || 2 | CHỈ SỐ QUÉT NHANH FULL | COUNT_PK | 848 nghìn | 589 (2) | 00:00:01 | -------------------------------------------- ------------------------------ Thông tin chiếu cột (được xác định bằng id hoạt động):---------- ------------------------------------------------- 1 - (# khóa =0) COUNT (*) [22] 2 - (tập hàng =1019) Lưu ý ----- - thống kê động được sử dụng:lấy mẫu động (cấp =2) 19 hàng được chọn. QL> SQL> SQL> thay đổi Phiên thiết lập sự kiện ='10053 theo dõi ngữ cảnh tên mãi mãi, cấp 2'; Phiên đã thay đổi.SQL> chọn số lượng (rowid) từ count_test; COUNT (ROWID) ------------ 1000000SQL> thay đổi sự kiện thiết lập phiên ='Tắt ngữ cảnh tên theo dõi 10053'; Phiên đã thay đổi.SQL> giải thích kế hoạch cho số lượng được chọn (rowid) từ count_test; Giải thích.SQL> chọn * từ bảng (dbms_xplan.display (null, null, 'chiếu')); PLAN_TABLE_OUTPUT- -------------------------------------------------- --------------------------------------- Giá trị băm của kế hoạch:371675025 ------ -------------------------------------------------- -------------------------- | Id | Hoạt động | Tên | Hàng | Số byte | Chi phí (% CPU) | Thời gian | ------------------------------------------------ ---------------------------------- | 0 | TUYỂN CHỌN BÁO CÁO | | 1 | 12 | 589 (2) | 00:00:01 || 1 | SẮP XẾP TỔNG HỢP | | 1 | 12 | | || 2 | CHỈ SỐ QUÉT NHANH FULL | COUNT_PK | 848 nghìn | 9941K | 589 (2) | 00:00:01 | -------------------------------------------- -------------------------------------- Thông tin chiếu cột (được xác định bằng id hoạt động):- -------------------------------------------------- ------- 1 - (# khóa =0) COUNT (ROWID) [22] 2 - (bộ hàng =256) ROWID [ROWID, 10] Lưu ý ----- - thống kê động được sử dụng:lấy mẫu động (cấp =2) 19 hàng được chọn. QL> SQL> offcommit spool; 

Chi tiết theo dõi 10053 không thay đổi sau khi khóa chính được thêm vào.

Có vẻ như hai phần thông tin đã được thu thập từ thử nghiệm này - số lượng (rowid) không tốt hơn số lượng (*) khi bảng chứa các cột CLOB và số lượng (*) không mở rộng danh sách cột như "select *" (và không có lý do gì để tin rằng điều đó nên xảy ra).

Bằng chứng là trong bánh pudding, như câu ngạn ngữ cũ.

# # #

Xem các bài viết của David Fitzjarrell


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Định cấu hình Hibernate để sử dụng SYS_GUID () của Oracle cho Khóa chính

  2. Hàm TAN () trong Oracle

  3. Ví dụ về câu lệnh Oracle FOR LOOP SELECT

  4. Cập nhật Salesforce từ Oracle®

  5. Phân tích cú pháp tên bảng và cột từ SQL / HQL Java