2009-09-04 3 views
5

डिफ़ॉल्ट रूप से ओरेकल बनाए गए इंडेक्स का उपयोग करता है।ओरेकल - मैं इंडेक्स कैसे बना सकता हूं जिसका उपयोग तब किया जाएगा जब NLS_COMP = भाषाई और NLS_Sort = Binary_CI

जब मैं NLS_COMP = भाषाई और NLS_Sort = Binary_CI में बदलता हूं, तो मुझे पूर्ण तालिका स्कैन मिलता है।

मैं कहीं पढ़ता हूं जो एक इंडेक्स बना रहा है (nlssort (name, 'NLS_SORT = BINARY_CI')); काम करेगा।

जैसा कि मेरा प्रयास नीचे दिखाता है, इतना नहीं। यहां तक ​​कि अगर मैं इसे मजबूर करता हूं, तो प्रदर्शन ऐसा प्रतीत नहीं होता है जो मैं अपेक्षा करता हूं। यह एक मामूली उदाहरण है जिसे मैं कई लाख पंक्तियों के साथ एक टेबल के लिए हल करना चाहता हूं, इसलिए पूर्ण टेबल स्कैन खराब होंगे।

तो सवाल यह है कि मैं इंडेक्स कैसे बना सकता हूं ताकि उनका उपयोग किया जा सके।

धन्यवाद

- सेटअप एक्स

create table x (name varchar2(30)) ; 
insert into x select table_name from all_tables; 
create index x_ix on x (name); 
create index x_ic on x (nlssort(name, 'NLS_SORT=BINARY_CI')); 
/ 

- सामान्य सेटिंग

ALTER SESSION SET NLS_COMP=BINARY; 
ALTER SESSION SET NLS_SORT=BINARY; 
/
set autotrace on 
/
select * from X where NAME like 'x%'; 

--0 rows selected 
-- 
--------------------------------------------------------------------------- 
--| Id | Operation  | Name | Rows | Bytes | Cost (%CPU)| Time  | 
--------------------------------------------------------------------------- 
--| 0 | SELECT STATEMENT |  |  1 | 17 |  1 (0)| 00:00:01 | 
--|* 1 | INDEX RANGE SCAN| X_IX |  1 | 17 |  1 (0)| 00:00:01 | 
--------------------------------------------------------------------------- 
/
set autotrace off 
/

- भाषाई

ALTER SESSION SET NLS_COMP=LINGUISTIC; 
ALTER SESSION SET NLS_SORT=BINARY_CI; 
/
set autotrace on 
/
select * from X where NAME like 'x%'; 
--13 rows selected 
-- 
---------------------------------------------------------------------------- 
--| Id | Operation   | Name | Rows | Bytes | Cost (%CPU)| Time  | 
---------------------------------------------------------------------------- 
--| 0 | SELECT STATEMENT |  |  1 | 17 |  3 (0)| 00:00:01 | 
--|* 1 | TABLE ACCESS FULL| X |  1 | 17 |  3 (0)| 00:00:01 | 
---------------------------------------------------------------------------- 

select /*+ INDEX(X X_IX   ) */ * from X where NAME like 'x%'; 
--13 rows selected 
-- 
--------------------------------------------------------------------------- 
--| Id | Operation  | Name | Rows | Bytes | Cost (%CPU)| Time  | 
--------------------------------------------------------------------------- 
--| 0 | SELECT STATEMENT |  |  1 | 17 |  9 (0)| 00:00:01 | 
--|* 1 | INDEX FULL SCAN | X_IX |  1 | 17 |  9 (0)| 00:00:01 | 
--------------------------------------------------------------------------- 

select /*+ INDEX(X X_IC   ) */ * from X where NAME like 'x%'; 
--13 rows selected 
-- 
-------------------------------------------------------------------------------------- 
--| Id | Operation     | Name | Rows | Bytes | Cost (%CPU)| Time  | 
-------------------------------------------------------------------------------------- 
--| 0 | SELECT STATEMENT   |  |  1 | 17 | 448 (1)| 00:00:06 | 
--|* 1 | TABLE ACCESS BY INDEX ROWID| X |  1 | 17 | 448 (1)| 00:00:06 | 
--| 2 | INDEX FULL SCAN   | X_IC | 1629 |  |  8 (0)| 00:00:01 | 
-------------------------------------------------------------------------------------- 
/

set autotrace off 
/
+4

मैं एक पुनरुत्पादित उदाहरण के लिए प्रशंसा देना चाहता था। कुडोस! –

उत्तर

1

मैं अपने परीक्षण पर अपनी खोज reproduced है डीबी (10.2.0.3)। जांच करने पर, ऐसा लगता है LIKE ऑपरेटर भाषाई सूचकांक का उपयोग नहीं कर सकते हैं - 10gR2 Documentation से:

एसक्यूएल कार्यों मैक्स() और मिन(), और यह भी पसंद ऑपरेटर, भाषाई अनुक्रमित जब NLS_COMP उपयोग नहीं कर सकते भाषाविज्ञान पर सेट है।

ऐसा लगता है कि भाषाई सूचकांक का मुख्य उद्देश्य एसओटी ऑपरेशन में सुधार करना है।

यदि आपका लक्ष्य इस कॉलम पर केस-असंवेदनशील तरीके से खोजना है, तो मेरा सुझाव है कि आप UPPER(name) पर एक अनुक्रमणिका बनाएं और इसके बजाय UPPER(name) LIKE UPPER('x%') पर अपनी क्वेरी बनाएं।

यदि आप एक और (अधिक जटिल) भाषाई सेटिंग का उपयोग करना चाहते हैं, तो आप Oracle Text indexes देख सकते हैं।

संपादित करें: एक और समाधान नहीं है: क्या आप की जगह ले सकता LIKE 'ABC%' साथ:

SQL> select * from x where name >= 'ABC' and name < 'ABD'; 

Execution Plan 
---------------------------------------------------------- 
Plan hash value: 708878862 

-------------------------------------------------------------------------------- 
| Id | Operation     | Name | Rows | Bytes | Cost (%CPU)| Time 
-------------------------------------------------------------------------------- 
| 0 | SELECT STATEMENT   |  |  1 | 24 |  4 (0)| 00:00: 
| 1 | TABLE ACCESS BY INDEX ROWID| X |  1 | 24 |  4 (0)| 00:00: 
|* 2 | INDEX RANGE SCAN   | X_IC |  1 |  |  3 (0)| 00:00: 
-------------------------------------------------------------------------------- 

अगर आप (<> और) तुलना ऑपरेटरों के साथ एक अभिव्यक्ति चाहते अभिव्यक्ति का अनुवाद कर सकते हैं आप देख सकते हैं भाषाई सूचकांक का उपयोग किया जा सकता है।

+0

मुझे "इन ('xx', 'yy', ...)" संरचना का उपयोग करते समय NLS_COMP वैरिएबल LINGUISTIC होने के कारण पूर्ण तालिका स्कैन भी मिला। – rpilkey

2

ओरेकल 11 जी के बाद - LIKE भाषाई सूचकांक का उपयोग कर सकते हैं। प्रलेखन के लिए संशोधित किया गया था:

The SQL functions MAX() and MIN() cannot use linguistic indexes when NLS_COMP is set to LINGUISTIC 

सूचना वे "और यह भी पसंद ऑपरेटर" हिस्सा निकाल दिया।

संबंधित मुद्दे

 संबंधित मुद्दे