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

Bỏ qua kiểm tra phân vùng phạm vi

Nếu không có kế hoạch giải thích hoặc bảng định nghĩa, thật khó để biết điều gì đang xảy ra. Dự đoán đầu tiên của tôi là bạn có các chỉ mục được phân vùng LOCAL mà không có year cột. Chúng trợ giúp với COUNT (*) trên một phân vùng, tuy nhiên, chúng dường như không được sử dụng khi bạn truy vấn một năm (ít nhất là trên 10.2.0.3).

Đây là một ví dụ nhỏ mô phỏng lại phát hiện của bạn (và một cách giải quyết):

SQL> CREATE TABLE DATA (
  2     YEAR NUMBER NOT NULL,
  3     ID NUMBER NOT NULL,
  4     extra CHAR(1000)
  5  ) PARTITION BY RANGE (YEAR) (
  6     PARTITION part1 VALUES LESS THAN (2010),
  7     PARTITION part2 VALUES LESS THAN (2011)
  8  );
Table created

SQL> CREATE INDEX ix_id ON DATA  (ID) LOCAL;
Index created

SQL> INSERT INTO DATA 
  2  (SELECT 2009+MOD(ROWNUM, 2), ROWNUM, 'A' FROM DUAL CONNECT BY LEVEL <=1e4);

10000 rows inserted

SQL> EXEC dbms_stats.gather_table_stats(USER, 'DATA', CASCADE=>TRUE);

PL/SQL procedure successfully completed

Bây giờ hãy so sánh hai kế hoạch giải thích:

SQL> SELECT COUNT(*) FROM DATA WHERE YEAR=2010;

Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=ALL_ROWS (Cost=197 Card=1 Bytes=4)
   1    0   SORT (AGGREGATE)
   2    1     PARTITION RANGE (SINGLE) (Cost=197 Card=5000 Bytes=20000)
   3    2       TABLE ACCESS (FULL) OF 'DATA' (TABLE) (Cost=197 Card=5000...)

SQL> SELECT COUNT(*) FROM DATA PARTITION (part1);

Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=ALL_ROWS (Cost=11 Card=1)
   1    0   SORT (AGGREGATE)
   2    1     PARTITION RANGE (SINGLE) (Cost=11 Card=5000)
   3    2       INDEX (FULL SCAN) OF 'IX_ID' (INDEX) (Cost=11 Card=5000)

Như bạn có thể thấy, chỉ mục không được sử dụng khi bạn truy vấn trực tiếp năm. Khi bạn thêm năm vào chỉ mục ĐỊA PHƯƠNG, nó sẽ được sử dụng. Tôi đã sử dụng lệnh COMPRESS 1 để yêu cầu Oracle nén cột đầu tiên. Chỉ mục kết quả có kích thước gần bằng với chỉ mục gốc (nhờ nén) nên hiệu suất sẽ không bị ảnh hưởng.

SQL> DROP INDEX ix_id;
 Index dropped

SQL> CREATE INDEX ix_id ON DATA (year, ID) LOCAL COMPRESS 1;
Index created

SQL> SELECT COUNT(*) FROM DATA WHERE YEAR=2010;

Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=ALL_ROWS (Cost=12 Card=1 Bytes=4)
   1    0   SORT (AGGREGATE)
   2    1     PARTITION RANGE (SINGLE) (Cost=12 Card=5000 Bytes=20000)
   3    2       INDEX (RANGE SCAN) OF 'IX_ID' (INDEX) (Cost=12 Card=5000...)


  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ông thể kết nối phiên bản RDS Oracle của tôi với máy chủ PHP

  2. Cách nhóm theo 1 trong SQL Server

  3. Làm cách nào để loại bỏ các thẻ XML trống không mong muốn?

  4. Hiểu hành vi của hàm remainder () trong Oracle

  5. Xóa một biểu thức ngẫu nhiên khỏi chuỗi