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

Các thay đổi kế hoạch thực thi Oracle SQL do chuyển đổi nội bộ SYS_OP_C2C

SYS_OP_C2C là một internal function thực hiện implicit conversion trong tổng số varchar2 thành national character set sử dụng TO_NCHAR hàm số. Do đó, bộ lọc thay đổi hoàn toàn so với bộ lọc sử dụng so sánh thông thường.

Tôi không chắc về lý do tại sao số lượng hàng lại ít hơn , nhưng tôi có thể đảm bảo rằng nó có thể còn nhiều hơn nữa cũng vậy. Ước tính chi phí sẽ không bị ảnh hưởng.

Hãy thử xem từng bước trong một trường hợp thử nghiệm.

SQL> CREATE TABLE t AS SELECT 'a'||LEVEL col FROM dual CONNECT BY LEVEL < 1000;

Table created.

SQL>
SQL> EXPLAIN PLAN FOR SELECT * FROM t WHERE col = 'a10';

Explained.

SQL> SELECT * FROM TABLE(dbms_xplan.display);

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------
Plan hash value: 1601196873

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |     1 |     5 |     3   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| T    |     1 |     5 |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------

   1 - filter("COL"='a10')

13 rows selected.

SQL>

Càng xa càng tốt. Vì chỉ có một hàng có giá trị là 'a10', trình tối ưu hóa đã ước tính một hàng.

Hãy xem với việc chuyển đổi bộ ký tự quốc gia.

SQL> EXPLAIN PLAN FOR SELECT * FROM t WHERE col = N'a10';

Explained.

SQL> SELECT * FROM TABLE(dbms_xplan.display);

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------
Plan hash value: 1601196873

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |    10 |    50 |     3   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| T    |    10 |    50 |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------

   1 - filter(SYS_OP_C2C("COL")=U'a10')

13 rows selected.

SQL>

Điều gì đã xảy ra ở đây? Chúng ta có thể thấy filter(SYS_OP_C2C("COL")=U'a10') , có nghĩa là một hàm nội bộ được áp dụng và nó chuyển đổi varchar2 giá trị thành nvarchar2 . Bộ lọc hiện đã tìm thấy 10 hàng.

Điều này cũng sẽ ngăn chặn bất kỳ việc sử dụng chỉ mục nào, vì bây giờ một hàm được áp dụng trên cột. Chúng tôi có thể điều chỉnh nó bằng cách tạo một function-based index để tránh full table scan .

SQL> create index nchar_indx on t(to_nchar(col));

Index created.

SQL>
SQL> EXPLAIN PLAN FOR SELECT * FROM t WHERE to_nchar(col) = N'a10';

Explained.

SQL> SELECT * FROM TABLE(dbms_xplan.display);

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------
Plan hash value: 1400144832

--------------------------------------------------------------------------------------------------
| Id  | Operation                           | Name       | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                    |            |    10 |    50 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID BATCHED| T          |    10 |    50 |     2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN                  | NCHAR_INDX |     4 |       |     1   (0)| 00:00:01 |
--------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------
---------------------------------------------------

   2 - access(SYS_OP_C2C("COL")=U'a10')

14 rows selected.

SQL>

Tuy nhiên, điều này sẽ làm cho các kế hoạch thực hiện tương tự? Không. Tôi nghĩ với hai bộ ký tự khác nhau , bộ lọc sẽ không được áp dụng giống nhau. Do đó, sự khác biệt nằm ở chỗ.

Nghiên cứu của tôi cho biết,



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. lỗi sql khi thực thi tập lệnh. thử xóa kho lưu trữ trước khi tạo kho lưu trữ

  2. Chức năng tổng hợp Oracle để phân bổ số tiền

  3. Tại sao bản cập nhật JDBC của tôi không hoạt động?

  4. REGEX để chọn giá trị thứ n từ danh sách, cho phép các giá trị rỗng

  5. Xóa truy vấn không hoạt động ứng dụng java biểu mẫu