Гость
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Использовать индекс / 15 сообщений из 15, страница 1 из 1
15.11.2021, 11:25
    #40112016
PaulWist
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использовать индекс
Братья по разуму, в Оракле я NULL.

Дано:

Код: plsql
1.
2.
3.
4.
5.
6.
-- Табличка
 CREATE TABLE "BAAN"."TTCIBD200711" 
   (	"T$ITEM" NVARCHAR2(47) NOT NULL ENABLE)
 
-- Индекс
 CREATE UNIQUE INDEX "BAAN"."TTCIBD200711$IDX1" ON "BAAN"."TTCIBD200711" (NLSSORT("T$ITEM",'nls_sort=''UCA0700_DUCET_S3_VN_BN_NY_EN_FN_HN_DN_MN''')) 



Ищу одну запись

Код: plsql
1.
2.
3.
SELECT 
T$ITEM from baan.ttcibd200711  where 
baan.ttcibd200711.t$item in ('бла-бла-бла')



В плане получаю
авторTABLE ACCESS -- FULL.

Пытаюсь добавить индекс

Код: plsql
1.
2.
3.
4.
SELECT 
/*+ INDEX(ttcibd200711 TTCIBD200711$IDX1)*/
T$ITEM, T$CWAR from baan.ttcibd200711  where 
baan.ttcibd200711.t$item in ('бла-бла-бла')



В плане получаю:
авторTABLE ACCESS -- BY INDEX ROWID BATCHED
INDEX -- FULL SCAN

Вопрос: Как заставить оптимизатор использовать индекс SEEK, что нужно написать в предикате для данного индекса.
...
Рейтинг: 0 / 0
15.11.2021, 11:43
    #40112023
PuM256
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использовать индекс
Что-то вы явно не договариваете. В DDL у вас только колонка T$ITEM, а в запросе ещё есть T$CWAR.
Так что приведите полный DDL таблицы и полный запрос без всяких "бла-бла-бла". На мой взгляд, вы упустили какую-то деталь, которая вам кажется неважной, но при этом она имеет решающее значение.

А хинты в таких простых случаях лучше вообще не использовать.
...
Рейтинг: 0 / 0
15.11.2021, 11:58
    #40112033
Asmodeus
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использовать индекс
PaulWist,

А индекс именно так кто-то заставляет создавать?
...
Рейтинг: 0 / 0
15.11.2021, 12:19
    #40112038
Asmodeus
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использовать индекс
PaulWist,

Вы как-то так хотите?

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
SQLcl> create table hr.t$drop
  2  (
  3      t_id    VARCHAR2 (47) not null enable
  4  );

Table HR.T$DROP created.

SQLcl> create unique index hr.i_t$drop_tid
  2      on hr.t$drop
  3      (nlssort (t_id, 'nls_sort=''UCA0700_DUCET_S3_VN_BN_NY_EN_FN_HN_DN_MN'''));

Index HR.I_T$DROP_TID created.

SQLcl> explain plan for
  2  select t_id
  3    from hr.t$drop
  4   where t_id in (:c);

Explained.

SQLcl> select * from table(dbms_xplan.display);

                                                              PLAN_TABLE_OUTPUT
_______________________________________________________________________________
Plan hash value: 3632732064

----------------------------------------------------------------------------
| Id  | Operation         | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |        |     1 |    25 |     2   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| T$DROP |     1 |    25 |     2   (0)| 00:00:01 |
----------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("T_ID"=:C)

Note
-----
   - dynamic statistics used: dynamic sampling (level=2)

17 rows selected.

SQLcl> select * from nls_session_parameters;

                 PARAMETER                         VALUE
__________________________ _____________________________
...
NLS_SORT                   RUSSIAN
NLS_COMP                   BINARY
...

17 rows selected.

SQLcl> alter session set nls_sort="UCA0700_DUCET_S3_VN_BN_NY_EN_FN_HN_DN_MN";

Session altered.

SQLcl> alter session set nls_comp=linguistic;

Session altered.

SQLcl> explain plan for
  2  select t_id
  3    from hr.t$drop
  4*  where t_id in (:c);

SQLcl> select * from table(dbms_xplan.display);

                                                                              PLAN_TABLE_OUTPUT
_______________________________________________________________________________________________
Plan hash value: 3730450835

--------------------------------------------------------------------------------------------
| Id  | Operation                   | Name         | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |              |     1 |   523 |     0   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| T$DROP       |     1 |   523 |     0   (0)| 00:00:01 |
|*  2 |   INDEX UNIQUE SCAN         | I_T$DROP_TID |     1 |       |     0   (0)| 00:00:01 |
--------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access(NLSSORT("T_ID",'nls_sort=''UCA0700_DUCET_S3_VN_BN_NY_EN_FN_HN_DN_MN'''
              )=NLSSORT(:C,'nls_sort=''UCA0700_DUCET_S3_VN_BN_NY_EN_FN_HN_DN_MN'''))

15 rows selected.

...
Рейтинг: 0 / 0
15.11.2021, 13:21
    #40112058
PaulWist
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использовать индекс
PuM256
Что-то вы явно не договариваете. В DDL у вас только колонка T$ITEM, а в запросе ещё есть T$CWAR.
Так что приведите полный DDL таблицы и полный запрос без всяких "бла-бла-бла". На мой взгляд, вы упустили какую-то деталь, которая вам кажется неважной, но при этом она имеет решающее значение.


2 PuM256

Это не принципиально, пусть DDL будет такое:

Код: plsql
1.
2.
3.
  CREATE TABLE "BAAN"."TTCIBD200711" 
   (	"T$ITEM" NVARCHAR2(47) NOT NULL ENABLE, 
	"T$CWAR" NVARCHAR2(6) NOT NULL ENABLE)



PuM256

А хинты в таких простых случаях лучше вообще не использовать.


Цель была, в принципе заставить искать по индексу, ... я прекрасно понимаю, что оптимизатор достаточно умный, что бы на тривиальном плане не найти индекс.

2 Asmodeus

Такой индекс - это реальность на которую я не могу повлиять :(

Правильно ли я понимаю, что бы использовался "такой" индекс надо выполнить:

Код: plsql
1.
alter session set nls_sort="UCA0700_DUCET_S3_VN_BN_NY_EN_FN_HN_DN_MN";



те изменить настройки сессии???
...
Рейтинг: 0 / 0
15.11.2021, 13:53
    #40112071
Asmodeus
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использовать индекс
PaulWist,

nls_comp тоже надо поменять. Это можно делать через logon-триггер.
...
Рейтинг: 0 / 0
15.11.2021, 14:51
    #40112091
PaulWist
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использовать индекс
Asmodeus,

ОК, спасибо!!! Получилось.
...
Рейтинг: 0 / 0
15.11.2021, 19:22
    #40112186
Правильный Вася
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использовать индекс
Если в таблице одна запись, как в примере, то оптимизатору без разницы, что сканировать - таблицу или индекс. А уж если в индексе нет нужных полей, выбираемых по SELECT, то уж тем более нет смысла его читать и потом читать таблицу - двойная работа.

Вообще же лучше почитать Кайта, например, для понимания механики и оптимизации создаваемых структур в БД.
...
Рейтинг: 0 / 0
15.11.2021, 19:55
    #40112193
witte
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использовать индекс
Правильный Вася
Если в таблице одна запись, как в примере, то оптимизатору без разницы, что сканировать - таблицу или индекс.

Точнее так: если таблица размером до 5 блоков включительно, ЕМНИП, то индекс не будет использоваться даже если он формально помогает найти строчку быстро. Таблица прочитается целиком, т.к. оптимизатор считает что так быстрее.
Правильный Вася
А уж если в индексе нет нужных полей, выбираемых по SELECT, то уж тем более нет смысла его читать и потом читать таблицу - двойная работа.

Это как? Если мне нужна строчка / немного строчек целиком из большой таблицы по индексу то Вы предполагаете что оптимизатор будет фуллсканить таблицу?
...
Рейтинг: 0 / 0
15.11.2021, 20:42
    #40112203
PaulWist
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использовать индекс
witte

Правильный Вася
А уж если в индексе нет нужных полей, выбираемых по SELECT , то уж тем более нет смысла его читать и потом читать таблицу - двойная работа.

Это как? Если мне нужна строчка / немного строчек целиком из большой таблицы по индексу то Вы предполагаете что оптимизатор будет фуллсканить таблицу?


Вы, видимо, невнимательно прочли, те на таблице есть индекс по полю А, а предикат SELECT-а ищет по полю В, то в этом случае действительно оптимизатор вынужден сканировать таблицу целиком (не берём ситуацию когда данные умещаются на странице-блоке)

Код: plsql
1.
2.
3.
create index idxA on table (A)

select * from table where B = ...
...
Рейтинг: 0 / 0
15.11.2021, 21:03
    #40112204
witte
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использовать индекс
PaulWist
witte

пропущено...

Это как? Если мне нужна строчка / немного строчек целиком из большой таблицы по индексу то Вы предполагаете что оптимизатор будет фуллсканить таблицу?


Вы, видимо, невнимательно прочли, те на таблице есть индекс по полю А, а предикат SELECT-а ищет по полю В, то в этом случае действительно оптимизатор вынужден сканировать таблицу целиком (не берём ситуацию когда данные умещаются на странице-блоке)

Код: plsql
1.
2.
3.
create index idxA on table (A)

select * from table where B = ...


Да, верно, понял как select a, b, а не то что предикат по полю b.
...
Рейтинг: 0 / 0
16.11.2021, 01:45
    #40112227
Sayan Malakshinov
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использовать индекс
Правильный Вася
Если в таблице одна запись, как в примере, то оптимизатору без разницы, что сканировать - таблицу или индекс. А уж если в индексе нет нужных полей, выбираемых по SELECT, то уж тем более нет смысла его читать и потом читать таблицу - двойная работа.

witte
Точнее так: если таблица размером до 5 блоков включительно, ЕМНИП, то индекс не будет использоваться даже если он формально помогает найти строчку быстро. Таблица прочитается целиком, т.к. оптимизатор считает что так быстрее.

ну не правда же...
minitab.sql
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
set echo on;
create table t(a unique, b) as
select 1,1 from dual;

select blocks from user_tables where table_name='T';

alter session set MAX_DUMP_FILE_SIZE = unlimited;
alter session set tracefile_identifier='minitab_ius';
alter session set events '10053 trace name context forever, level 1';

alter session set tracefile_identifier='minitab_ius';
select * from t where a=1;
alter session set tracefile_identifier='minitab_fts';
select/*+ full(t) */ * from t where a=1;
alter session set tracefile_identifier='end';
alter session set events '10053 off';
set echo off;


plans
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
SQL_ID  g36j00khg170d, child number 0
-------------------------------------
select * from t where a=1

Plan hash value: 2971698376

-------------------------------------------------------------------------------------------
| Id  | Operation                   | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |             |       |       |     1 (100)|          |
|   1 |  TABLE ACCESS BY INDEX ROWID| T           |     1 |     6 |     1   (0)| 00:00:01 |
|*  2 |   INDEX UNIQUE SCAN         | SYS_C009298 |     1 |       |     0   (0)|          |
-------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("A"=1)

SQL_ID  2bkjh9149pjqq, child number 0
-------------------------------------
select/*+ full(t) */ * from t where a=1

Plan hash value: 1601196873

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |       |       |     3 (100)|          |
|*  1 |  TABLE ACCESS FULL| T    |     1 |     6 |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("A"=1)


full-output
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
SQL> create table t(a unique, b) as
  2  select 1,1 from dual;

Table created.

SQL>
SQL> select blocks from user_tables where table_name='T';

    BLOCKS
----------
         4

SQL>
SQL> alter session set MAX_DUMP_FILE_SIZE = unlimited;

Session altered.

SQL> alter session set tracefile_identifier='minitab_ius';

Session altered.

SQL> alter session set events '10053 trace name context forever, level 1';

Session altered.

SQL>
SQL> alter session set tracefile_identifier='minitab_ius';

Session altered.

SQL> select * from t where a=1;

         A          B
---------- ----------
         1          1

SQL> alter session set tracefile_identifier='minitab_fts';

Session altered.

SQL> select/*+ full(t) */ * from t where a=1;

         A          B
---------- ----------
         1          1

SQL> alter session set tracefile_identifier='end';

Session altered.

SQL> alter session set events '10053 off';

Session altered.

SQL> set echo off;

SQL> @tracefile_by_mask.sql minitab

ADR_HOME                                 TRACE_FILENAME                                CHANGE_TIME     MODIFY_TIME
---------------------------------------- --------------------------------------------- --------------- ---------------
/opt/oracle/diag/rdbms/ora19/ORA19       ORA19_ora_18263_minitab_ius.trc               nov/15 22:28:29 nov/15 22:28:29
/opt/oracle/diag/rdbms/ora19/ORA19       ORA19_ora_18263_minitab_fts.trc               nov/15 22:28:29 nov/15 22:28:29

SQL> @tracefile_spool.sql ORA19_ora_18263_minitab_ius.trc /mnt/d/temp/local/ORA19_ora_18263_minitab_ius.trc
SQL> @tracefile_spool.sql ORA19_ora_18263_minitab_fts.trc /mnt/d/temp/local/ORA19_ora_18263_minitab_fts.trc

SQL> @plan g36j00khg170d

Childs:

CHILD_NUMBER
------------
           0


P P_FORMAT
- ---------------
  typical


PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------
SQL_ID  g36j00khg170d, child number 0
-------------------------------------
select * from t where a=1

Plan hash value: 2971698376

-------------------------------------------------------------------------------------------
| Id  | Operation                   | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |             |       |       |     1 (100)|          |
|   1 |  TABLE ACCESS BY INDEX ROWID| T           |     1 |     6 |     1   (0)| 00:00:01 |
|*  2 |   INDEX UNIQUE SCAN         | SYS_C009298 |     1 |       |     0   (0)|          |
-------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("A"=1)


19 rows selected.

SQL> @plan 2bkjh9149pjqq

Childs:

CHILD_NUMBER
------------
           0


P P_FORMAT
- ---------------
  typical


PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------
SQL_ID  2bkjh9149pjqq, child number 0
-------------------------------------
select/*+ full(t) */ * from t where a=1

Plan hash value: 1601196873

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |       |       |     3 (100)|          |
|*  1 |  TABLE ACCESS FULL| T    |     1 |     6 |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("A"=1)


18 rows selected.



Модератор: Вложение удалено.
...
Рейтинг: 0 / 0
16.11.2021, 01:50
    #40112228
Sayan Malakshinov
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использовать индекс
картинка с планами под спойлером
...
Рейтинг: 0 / 0
16.11.2021, 19:07
    #40112389
Правильный Вася
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использовать индекс
witte
Правильный Вася
А уж если в индексе нет нужных полей, выбираемых по SELECT, то уж тем более нет смысла его читать и потом читать таблицу - двойная работа.

Это как? Если мне нужна строчка / немного строчек целиком из большой таблицы по индексу то Вы предполагаете что оптимизатор будет фуллсканить таблицу?

Вы вырвали предложение из контекста про одну запись в таблице. Если индекс не содержит всё, что нужно выбрать, то нет смысла в двойном чтении.

Sayan Malakshinov
ну не правда же...

Боюсь, что это зависит от наличия адекватной статистики, размеров блоков и прочих настроек.
...
Рейтинг: 0 / 0
17.11.2021, 02:27
    #40112439
Sayan Malakshinov
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использовать индекс
Правильный Вася

Боюсь, что это зависит от наличия адекватной статистики, размеров блоков и прочих настроек.
это стандартное поведение с адекватной статистикой, дефолтными параметрами и стандартным размером блока 8к
¯\_(ツ)_/¯
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Использовать индекс / 15 сообщений из 15, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]