नहीं, आपकी दूसरी तालिका में शामिल होने के अलावा, कोई अन्य तरीका नहीं है। निश्चित रूप से, आप अपने चुने हुए खंड में एक स्केलर सबक्वायरी लिख सकते हैं, या आप अपना खुद का फ़ंक्शन लिख सकते हैं, लेकिन यह अक्षम अभ्यास होगा।
आप तालिका से डेटा की जरूरत है, तो आप इसे से चयन करने की जरूरत है।
संपादित करें: मुझे अक्षम अभ्यास के बारे में अपने पहले के बयान को परिष्कृत करना होगा।
अपनी चुनी सूची में स्केलर सबक्वायरी का उपयोग करते समय, आप उम्मीद करेंगे कि आप नेस्टेड-लूप लुक-ए-जैसी योजना को मजबूर कर रहे हैं, जहां स्केलर सबक्वायरी राज्य_टेबल की प्रत्येक पंक्ति के लिए निष्पादित हो जाती है। कम से कम मुझे उम्मीद थी कि :-)।
हालांकि, ओरेकल ने स्केलर सबक्वायरी कैशिंग को कार्यान्वित किया है, जो वास्तव में एक अच्छा अनुकूलन की ओर जाता है। यह केवल subquery 3 बार निष्पादित करता है। स्केलर सबक्वायरीज़ के बारे में एक उत्कृष्ट लेख है जहां आप देख सकते हैं कि इस अनुकूलन में कैसा व्यवहार होता है: http://www.oratechinfo.co.uk/scalar_subqueries.html#scalar3
यह काम पर देखने के लिए मेरा स्वयं का परीक्षण है।
create table states_table (id,state,filler)
as
select level
, floor(dbms_random.value(0,3))
, lpad('*',1000,'*')
from dual
connect by level <= 100000
/
alter table states_table add primary key (id)
/
create table lookup_table (state_num,state_desc)
as
select 0, 'initial' from dual union all
select 1, 'current' from dual union all
select 2, 'final' from dual
/
alter table lookup_table add primary key (state_num)
/
alter table states_table add foreign key (state) references lookup_table(state_num)
/
exec dbms_stats.gather_table_stats(user,'states_table',cascade=>true)
exec dbms_stats.gather_table_stats(user,'lookup_table',cascade=>true)
फिर क्वेरी निष्पादित और वास्तविक कार्य योजना लागू करके पर एक नजर है:
SQL> select /*+ gather_plan_statistics */
2 s.id
3 , s.state
4 , l.state_desc
5 from states_table s
6 join lookup_table l on s.state = l.state_num
7/
ID STATE STATE_D
---------- ---------- -------
1 2 final
...
100000 0 initial
100000 rows selected.
SQL> select * from table(dbms_xplan.display_cursor(null,null,'allstats last'))
2/
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------
SQL_ID f6p6ku8g8k95w, child number 0
-------------------------------------
select /*+ gather_plan_statistics */ s.id , s.state , l.state_desc from states_table s join
lookup_table l on s.state = l.state_num
Plan hash value: 1348290364
---------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads | OMem | 1Mem | Used-Mem |
---------------------------------------------------------------------------------------------------------------------------------
|* 1 | HASH JOIN | | 1 | 99614 | 100K|00:00:00.50 | 20015 | 7478 | 1179K| 1179K| 578K (0)|
| 2 | TABLE ACCESS FULL| LOOKUP_TABLE | 1 | 3 | 3 |00:00:00.01 | 3 | 0 | | | |
| 3 | TABLE ACCESS FULL| STATES_TABLE | 1 | 99614 | 100K|00:00:00.30 | 20012 | 7478 | | | |
---------------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("S"."STATE"="L"."STATE_NUM")
20 rows selected.
अब अदिश सबक्वेरी संस्करण के लिए भी ऐसा ही करने के लिए अपने टेबल के अनुकरण के लिए, मैं इस स्क्रिप्ट प्रयोग किया है:
SQL> select /*+ gather_plan_statistics */
2 s.id
3 , s.state
4 , (select l.state_desc
5 from lookup_table l
6 where l.state_num = s.state
7 )
8 from states_table s
9/
ID STATE (SELECT
---------- ---------- -------
1 2 final
...
100000 0 initial
100000 rows selected.
SQL> select * from table(dbms_xplan.display_cursor(null,null,'allstats last'))
2/
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------
SQL_ID 22y3dxukrqysh, child number 0
-------------------------------------
select /*+ gather_plan_statistics */ s.id , s.state , (select l.state_desc
from lookup_table l where l.state_num = s.state ) from states_table s
Plan hash value: 2600781440
---------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads |
---------------------------------------------------------------------------------------------------------------
| 1 | TABLE ACCESS BY INDEX ROWID| LOOKUP_TABLE | 3 | 1 | 3 |00:00:00.01 | 5 | 0 |
|* 2 | INDEX UNIQUE SCAN | SYS_C0040786 | 3 | 1 | 3 |00:00:00.01 | 2 | 0 |
| 3 | TABLE ACCESS FULL | STATES_TABLE | 1 | 99614 | 100K|00:00:00.30 | 20012 | 9367 |
---------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("L"."STATE_NUM"=:B1)
20 rows selected.
और चरण 1 और 2 के स्टार्ट कॉलम को देखें: केवल 3!
इस अनुकूलन हमेशा अपनी स्थिति में एक अच्छी बात है या नहीं, कई कारकों पर निर्भर करता है। आप कुछ के प्रभाव को देखने के लिए पहले उल्लिखित आलेख को देख सकते हैं।
केवल तीन राज्यों के साथ अपनी स्थिति में, ऐसा लगता है जैसे आप अदिश सबक्वेरी संस्करण के साथ गलत नहीं जा सकते लग रहा है।
सम्मान, रॉब।
सच है, यह संभव है। लेकिन सलाह नहीं है। मैं अपना जवाब फिर से लिखूंगा हालांकि :-) –
यह बस ऐसा करेगा। मैं इस अभ्यास के व्यापार से बहुत परिचित नहीं हूं, लेकिन यदि एक छोटी सी क्वेरी के साथ मैं एक बड़े पैमाने पर डीकोड कर रहा हूं तो यह बहुत गन्दा हो जाएगा :(@ammoQ, क्या आपके पास डिफ़ॉल्ट मान के लिए कोई सुझाव होगा? चीयर्स! – filippo
संपादित करें : एक डिफ़ॉल्ट मान –