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

Xem xét từng lỗi từng nhóm của Oracle

Oracle đã giới thiệu một tính năng mới, nhóm theo loại bỏ, cho các truy vấn trong đó nhóm theo cột cũng là khóa duy nhất của bảng. Như với nhiều tính năng mới, tính năng này vẫn chưa được giải quyết hết. Vấn đề nảy sinh khi các giá trị khóa được thao tác với các lệnh gọi hàm. Ví dụ sau sẽ minh họa vấn đề bằng cách sử dụng bảng có DATE làm khóa chính và bằng cách trích xuất năm được trích xuất bằng TO_CHAR hoặc EXTRACT.

Một bảng được tạo như sau:

create table bug_test_calendar(
        cal_name   char(17),
        bus_dt   date,
        updt_timestamp       timestamp (6) default systimestamp,
        constraint pk_bug_test_calendar 
                        primary key (bus_dt)
)
/

insert into bug_test_calendar (bus_dt)
select
        sysdate + 10 * rownum
from 
        all_objects 
where 
        rownum <= 40 
/

commit;

Khi truy vấn hiển thị bên dưới được thực thi, nó tạo ra các kết quả sau:

select
        to_char(bus_dt,'YYYY') bus_dt, count(*) ct
from
       bug_test_calendar
group by 
        to_char(bus_dt,'YYYY')
order by 
        to_char(bus_dt,'YYYY')
/


BUS_DF   CT
-------  --
2020      1
2020      1
...
2020      1

40 rows returned

Oracle không 'biết' rằng các giá trị khóa đã bị thao túng để chúng không còn là duy nhất, do đó, trình tối ưu hóa áp dụng loại bỏ từng nhóm dựa trên khóa duy nhất với kết quả ít xuất sắc hơn,

CHIẾT KHẤU giá vé không thể tốt hơn, trả về kết quả tương tự. Hành vi này được kiểm soát bởi tham số “_optimizer_aggr_groupby_elim”, được đặt thành true theo mặc định. Vì là thông số ẩn nên cài đặt của nó không được Oracle báo cáo trong một trong hai chế độ xem V $ PARAMEter hoặc V $ SPPARAMETER. Công việc xung quanh là chỉ cần đặt tham số này thành false. Tuy nhiên, việc kích hoạt nó có thể giúp ích cho các truy vấn theo nhóm khác trong đó các giá trị khóa duy nhất không bị thao túng.

Nhập Oracle 19c, trong đó chức năng này đã được sửa một phần:

select
        to_char(bus_dt,'YYYY') bus_dt, count(*) ct
from
       bug_test_calendar
group by 
        to_char(bus_dt,'YYYY')
order by 
        to_char(bus_dt,'YYYY')
/


BUS_DF   CT
-------  --
2020     40


Thật không may, EXTRACT vẫn bị hỏng trong 19c:

select
        to_char(bus_dt,'YYYY') bus_dt, count(*) ct
from
       bug_test_calendar
group by 
        extract(year deom bus_dt)
order by 
        extract(year deom bus_dt)
/


BUS_DF   CT
-------  ==
2020      1
2020      1
...
2020      1

40 rows returned

Rõ ràng là được cung cấp các giá trị khóa thực sự duy nhất, một truy vấn theo nhóm sẽ tạo ra số lượng là 1 cho mỗi khóa. Và, hiển nhiên, Oracle sẽ có thể nhận ra khi nào các giá trị không còn là duy nhất và gọi ra cơ chế theo nhóm thích hợp. Vẫn còn phải xem các phiên bản sau 19c có khắc phục được điều kiện thứ hai hay không và do đó trả lại kết quả chính xác mà không cần phải tắt tính năng này.

Điều này có thể không ảnh hưởng đến mọi cài đặt Oracle mới hơn 12.1, nhưng điều đáng biết là nếu kết quả sai bắt đầu xuất hiện trong nhóm đã chọn theo truy vấn.

# # #

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. Khớp các giá trị cột trùng lặp của Oracle bằng cách sử dụng Soundex, Jaro Winkler và Chỉnh sửa Khoảng cách (UTL_MATCH)

  2. cách viết truy vấn sql

  3. Oracle Regexp để thay thế \ n, \ r và \ t bằng khoảng trắng

  4. Oracle 12.2 Sharding

  5. Làm thế nào để cài đặt ruby-oci8?