व्याख्या योजना या तालिका परिभाषा के बिना यह बताना वास्तव में कठिन है कि क्या चल रहा है। मेरा पहला अनुमान यह है कि आपके पास year
. के बिना LOCAL विभाजन अनुक्रमित हैं कॉलम। वे एक विभाजन पर COUNT(*) के साथ मदद करते हैं, हालांकि ऐसा लगता है कि जब आप एक वर्ष (कम से कम 10.2.0.3 पर) क्वेरी करते हैं तो उनका उपयोग नहीं किया जाता है।
यहां एक छोटा सा उदाहरण दिया गया है जो आपकी खोज (और एक समाधान) को पुन:प्रस्तुत करता है:
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
अब दो व्याख्या योजनाओं की तुलना करें:
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)
जैसा कि आप देख सकते हैं कि सूचकांक नहीं है जब आप सीधे वर्ष की क्वेरी करते हैं तो इसका उपयोग किया जाता है। जब आप वर्ष को LOCAL अनुक्रमणिका में जोड़ते हैं तो इसका उपयोग किया जाएगा। मैंने पहले कॉलम को संपीड़ित करने के लिए Oracle को बताने के लिए COMPRESS 1 निर्देश का उपयोग किया। परिणामी सूचकांक मूल सूचकांक (संपीड़न के लिए धन्यवाद) के आकार के लगभग समान है, इसलिए प्रदर्शन प्रभावित नहीं होना चाहिए।
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...)