मेरे पास 1.5 मिलियन पंक्तियों वाली एक तालिका है। मैं एक क्वेरी चलाता हूं जो कॉलम में गैर-दोहराने वाले मान वाले रिकॉर्ड प्राप्त करता है। मैं एक ऐसा व्यवहार देख रहा हूं जिसमें इंडेक्स बनाने के बाद क्वेरी का प्रदर्शन घट जाता है। मैंने आंकड़ों को इकट्ठा करने के लिए 100% अनुमान प्रतिशत (गणना मोड) के साथ dbms_stats का भी उपयोग किया ताकि ओरेकल 11 जी सीबीओ क्वेरी प्लान के लिए एक अधिक सूचित निर्णय लेता है, लेकिन यह क्वेरी निष्पादन समय में सुधार नहीं करता है।इंडेक्स बनने के बाद क्वेरी धीमी गति से निष्पादित होती है और dbms_stats गणना का उपयोग किया जाता है
SQL> desc tab3;
Name Null? Type
----------------------------------------------
COL1 NUMBER(38)
COL2 VARCHAR2(100)
COL3 VARCHAR2(36)
COL4 VARCHAR2(36)
COL5 VARCHAR2(4000)
COL6 VARCHAR2(4000)
MEASURE_0 VARCHAR2(4000)
MEASURE_1 VARCHAR2(4000)
MEASURE_2 VARCHAR2(4000)
MEASURE_3 VARCHAR2(4000)
MEASURE_4 VARCHAR2(4000)
MEASURE_5 VARCHAR2(4000)
MEASURE_6 VARCHAR2(4000)
MEASURE_7 VARCHAR2(4000)
MEASURE_8 VARCHAR2(4000)
MEASURE_9 VARCHAR2(4000)
कॉलम measure_0
में 0.4 मिलियन अद्वितीय मूल्य हैं।
SQL> select count(*) from (select measure_0 from tab3 group by measure_0 having count(*) = 1) abc;
COUNT(*)
----------
403664
निष्पादन योजना के साथ निम्नलिखित प्रश्न है, कृपया ध्यान दें कि तालिका पर कोई अनुक्रमणिका नहीं है।
SQL> set autotrace traceonly;
SQL> SELECT * FROM (
2 SELECT
3 (ROWNUM -1) AS COL1,
4 ft.COL1 AS OLD_COL1,
5 ft.COL2,
6 ft.COL3,
7 ft.COL4,
8 ft.COL5,
9 ft.COL6,
10 ft.MEASURE_0,
11 ft.MEASURE_1,
12 ft.MEASURE_2,
13 ft.MEASURE_3,
14 ft.MEASURE_4,
15 ft.MEASURE_5,
16 ft.MEASURE_6,
17 ft.MEASURE_7,
18 ft.MEASURE_8,
19 ft.MEASURE_9
20 FROM tab3 ft
21 WHERE MEASURE_0 IN
22 (
23 SELECT MEASURE_0
24 FROM tab3
25 GROUP BY MEASURE_0
26 HAVING COUNT(*) = 1
27 )
28 ) ABC WHERE COL1 >= 0 AND COL1 <=449;
450 rows selected.
Elapsed: 00:00:01.90
Execution Plan
----------------------------------------------------------
Plan hash value: 3115757351
------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1243 | 28M| 717K (1)| 02:23:29 |
|* 1 | VIEW | | 1243 | 28M| 717K (1)| 02:23:29 |
| 2 | COUNT | | | | | |
|* 3 | HASH JOIN | | 1243 | 30M| 717K (1)| 02:23:29 |
| 4 | VIEW | VW_NSO_1 | 1686K| 3219M| 6274 (2)| 00:01:16 |
|* 5 | FILTER | | | | | |
| 6 | HASH GROUP BY | | 1 | 3219M| 6274 (2)| 00:01:16 |
| 7 | TABLE ACCESS FULL| TAB3 | 1686K| 3219M| 6196 (1)| 00:01:15 |
| 8 | TABLE ACCESS FULL | TAB3 | 1686K| 37G| 6211 (1)| 00:01:15 |
------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("COL1">=0 AND "COL1"<=449)
3 - access("MEASURE_0"="MEASURE_0")
5 - filter(COUNT(*)=1)
Note
-----
- dynamic sampling used for this statement (level=2)
Statistics
----------------------------------------------------------
354 recursive calls
0 db block gets
46518 consistent gets
45122 physical reads
0 redo size
43972 bytes sent via SQL*Net to client
715 bytes received via SQL*Net from client
31 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
450 rows processed
क्वेरी 1.90 सेकंड लेता है। यदि मैं फिर से क्वेरी चलाता हूं तो यह 1.66 सेकंड लेता है। पहले रन में अधिक समय क्यों लगता है?
इसे गति देने के लिए मैंने क्वेरी में उपयोग किए गए दो कॉलम पर इंडेक्स बनाए।
SQL> create index ind_tab3_orgid on tab3(COL1);
Index created.
Elapsed: 00:00:01.68
SQL> create index ind_tab3_msr_0 on tab3(measure_0);
Index created.
Elapsed: 00:00:01.83
जब मैं पहली बार इस के बाद आप क्वेरी निकाल दिया यह एक काली सेकण्ड लगे वापस आने के लिए। जबकि बाद के रनों ने इसे 2.9 सेकंड में खरीदा। पहले भाग में ओरेकल इतना समय क्यों लेता है, क्या यह गर्म हो रहा है या कुछ .. मुझे परेशान करता है!
यह योजना जब यह लेता 2.9 seconds-
450 rows selected.
Elapsed: 00:00:02.92
Execution Plan
----------------------------------------------------------
Plan hash value: 240271480
-------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1243 | 28M| 711K (1)| 02:22:15 |
|* 1 | VIEW | | 1243 | 28M| 711K (1)| 02:22:15 |
| 2 | COUNT | | | | | |
| 3 | NESTED LOOPS | | | | | |
| 4 | NESTED LOOPS | | 1243 | 30M| 711K (1)| 02:22:15 |
| 5 | VIEW | VW_NSO_1 | 1686K| 3219M| 6274 (2)| 00:01:16 |
|* 6 | FILTER | | | | | |
| 7 | HASH GROUP BY | | 1 | 3219M| 6274 (2)| 00:01:16 |
| 8 | TABLE ACCESS FULL | TAB3 | 1686K| 3219M| 6196 (1)| 00:01:15 |
|* 9 | INDEX RANGE SCAN | IND_TAB3_MSR_0 | 1243 | | 2 (0)| 00:00:01 |
| 10 | TABLE ACCESS BY INDEX ROWID| TAB3 | 1243 | 28M| 44 (0)| 00:00:01 |
-------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("COL1">=0 AND "COL1"<=449)
6 - filter(COUNT(*)=1)
9 - access("MEASURE_0"="MEASURE_0")
Note
-----
- dynamic sampling used for this statement (level=2)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
660054 consistent gets
22561 physical reads
0 redo size
44358 bytes sent via SQL*Net to client
715 bytes received via SQL*Net from client
31 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
450 rows processed
मैं समय उम्मीद कर रहा था की तुलना में जब तालिका गैर अनुक्रमित था कम हो रहा है। तालिका के अनुक्रमित संस्करण को गैर अनुक्रमित संस्करण की तुलना में परिणामों को लाने के लिए अधिक समय क्यों लगता है? अगर मैं गलत नहीं हूं तो यह इंडेक्स रॉयड द्वारा टेबल एक्सेस है जो समय ले रहा है। क्या मैं टेबल एक्सेस का उपयोग करने के लिए ऑरैकल लागू कर सकता हूं?
तब मैंने टेबल पर आंकड़े एकत्र किए ताकि सीबीओ गणना विकल्प के साथ योजना में सुधार करे। तो अब आंकड़े सटीक होंगे।
SQL> EXECUTE dbms_stats.gather_table_stats (ownname=>'EQUBE67DP', tabname=>'TAB3',estimate_percent=>null,cascade=>true);
PL/SQL procedure successfully completed.
Elapsed: 00:01:02.47
SQL> set autotrace off;
SQL> select COLUMN_NAME,NUM_DISTINCT,SAMPLE_SIZE,HISTOGRAM,LAST_ANALYZED from dba_tab_cols where table_name = 'TAB3' ;
COLUMN_NAME NUM_DISTINCT SAMPLE_SIZE HISTOGRAM LAST_ANALYZED
------------------------------ ------------ ----------- --------------- ---------
COL1 1502257 1502257 NONE 27-JUN-12
COL2 0 NONE 27-JUN-12
COL3 1 1502257 NONE 27-JUN-12
COL4 0 NONE 27-JUN-12
COL5 1502257 1502257 NONE 27-JUN-12
COL6 1502257 1502257 NONE 27-JUN-12
MEASURE_0 405609 1502257 HEIGHT BALANCED 27-JUN-12
MEASURE_1 128570 1502257 NONE 27-JUN-12
MEASURE_2 1502257 1502257 NONE 27-JUN-12
MEASURE_3 185657 1502257 NONE 27-JUN-12
MEASURE_4 901 1502257 NONE 27-JUN-12
MEASURE_5 17 1502257 NONE 27-JUN-12
MEASURE_6 2202 1502257 NONE 27-JUN-12
MEASURE_7 2193 1502257 NONE 27-JUN-12
MEASURE_8 21 1502257 NONE 27-JUN-12
MEASURE_9 27263 1502257 NONE 27-JUN-12
मैं फिर से क्वेरी
450 rows selected.
Elapsed: 00:00:02.95
Execution Plan
----------------------------------------------------------
Plan hash value: 240271480
-------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 31M| 718G| 8046 (2)| 00:01:37 |
|* 1 | VIEW | | 31M| 718G| 8046 (2)| 00:01:37 |
| 2 | COUNT | | | | | |
| 3 | NESTED LOOPS | | | | | |
| 4 | NESTED LOOPS | | 31M| 62G| 8046 (2)| 00:01:37 |
| 5 | VIEW | VW_NSO_1 | 4057 | 7931K| 6263 (2)| 00:01:16 |
|* 6 | FILTER | | | | | |
| 7 | HASH GROUP BY | | 1 | 20285 | 6263 (2)| 00:01:16 |
| 8 | TABLE ACCESS FULL | TAB3 | 1502K| 7335K| 6193 (1)| 00:01:15 |
|* 9 | INDEX RANGE SCAN | IND_TAB3_MSR_0 | 4 | | 2 (0)| 00:00:01 |
| 10 | TABLE ACCESS BY INDEX ROWID| TAB3 | 779K| 75M| 3 (0)| 00:00:01 |
-------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("COL1">=0 AND "COL1"<=449)
6 - filter(COUNT(*)=1)
9 - access("MEASURE_0"="MEASURE_0")
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
660054 consistent gets
22561 physical reads
0 redo size
44358 bytes sent via SQL*Net to client
715 bytes received via SQL*Net from client
31 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
450 rows processed
भाग गया इस बार क्वेरी 2.9 सेकंड में वापस आ गया है (कभी कभी यह 3.9 सेकंड भी लिया)।
मेरा लक्ष्य क्वेरी निष्पादन समय जितना संभव हो कम से कम करना है। लेकिन इंडेक्स जोड़ने या आंकड़ों की गणना करने के बाद क्वेरी समय बढ़ रहा है। यह क्यों हो रहा है और इंडेक्स को रखकर मैं कैसे सुधार कर सकता हूं?
निष्पादन योजना ** ** ** सूचकांक क्या है? –
क्वेरी को पहली बार चलाने में अधिक समय क्यों लगता है? एक बात के लिए, यह ऑटोट्रेस द्वारा रिपोर्ट की गई 254 रिकर्सिव एसक्यूएल कॉल है। सेमेन्टिक्स के लिए क्वेरी को पार्स करने के लिए किए जाने वाले सभी काम (संदर्भित वस्तुओं और नाम मौजूद हैं और क्या आपके पास उनके पास विशेषाधिकार हैं), और उसके बाद निष्पादन योजना तैयार करने के लिए काम (कौन से इंडेक्स उपलब्ध हैं, लागत अनुमानित करें विभिन्न संभावित योजनाओं के)। उस पहले निष्पादन पर वहां बहुत भारी भारोत्तोलन किया जा रहा है। – spencer7593
आपकी दूसरी क्वेरी पर, जो 2 9 सेकेंड पहले रन लेता है, संभवतः शारीरिक पढ़ता है ... ओरेकल डिस्क से ब्लॉक प्राप्त कर रहा है और बफर कैश भर रहा है। (ऑटोट्रेस इस का एक सारांश दिखाएगा, एक कार्यक्रम 10046 ट्रेस में सभी प्रतीक्षाों के लिए विवरण होगा।) – spencer7593