Модераторы: LSD

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Join индексирование 
:(
    Опции темы
setnull
Дата 16.6.2009, 11:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 417
Регистрация: 3.7.2007

Репутация: 1
Всего: 1



Все здравствуйте!

Есть внешний ключ. Допустимо пустое значение. Пустое значение логически соответствует принадлежности всем записям родительской таблицы.

Условие присоединения
Код

... PAR_TABLE
INNER JOIN CHILD_TABLE ON 
        CHILD_TABLE.PAR IS NULL OR CHILD_TABLE.PAR = PAR_TABLE."ID"


делает выборку по таблице CHILD_TABLE FULL SCAN и она получается не индексированной.

Что можно сделать?

Спасибо!!!!
PM MAIL   Вверх
Zloxa
Дата 16.6.2009, 13:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3473
Регистрация: 12.9.2008

Репутация: 37
Всего: 161



Цитата(setnull @  16.6.2009,  11:49 Найти цитируемый пост)
Пустое значение логически соответствует принадлежности всем записям родительской таблицы.

кхе...  в топку бы такое smile
Цитата(setnull @  16.6.2009,  11:49 Найти цитируемый пост)
Что можно сделать?

под стать дизайну и решение.
Для того чтобы значение индекса не принимало не определенные значение - используем составной индекс, в который добавляем любое нот нулл поле, в результате получаем возможность индексного доступа по null.
Код

Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 

create table par(id primary key) as select level from dual connect by level <=1e5;
 
Table created
create table child(id primary key,par_id) as select level,decode(mod(level,1e5),0,cast(null as number),mod(level,1e5)+1) from dual connect by level <= 1e6;
 
Table created
create index child$par_id on child(par_id,id);
 
Index created

explain plan for
 select *
   from par
   inner join child on child.par_id is null
                       or child.par_id = par.id
 where par.id = :val;
 
Explained
select * from table(dbms_xplan.display);
 
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 2063622911
--------------------------------------------------------------------------------
| Id  | Operation           | Name         | Rows  | Bytes | Cost (%CPU)| Time
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |              |   430 | 16770 |    78   (2)| 00:00:
|   1 |  CONCATENATION      |              |       |       |            |
|   2 |   NESTED LOOPS      |              |    13 |   507 |     3   (0)| 00:00:
|*  3 |    INDEX UNIQUE SCAN| SYS_C0034093 |     1 |    13 |     1   (0)| 00:00:
|*  4 |    INDEX RANGE SCAN | CHILD$PAR_ID |    13 |   338 |     2   (0)| 00:00:
|   5 |   NESTED LOOPS      |              |   417 | 16263 |    75   (2)| 00:00:
|*  6 |    INDEX UNIQUE SCAN| SYS_C0034093 |     1 |    13 |     1   (0)| 00:00:
|*  7 |    INDEX RANGE SCAN | CHILD$PAR_ID |   417 | 10842 |    74   (2)| 00:00:
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   3 - access("PAR"."ID"=TO_NUMBER(:VAL))
   4 - access("CHILD"."PAR_ID"="PAR"."ID")
 
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
   6 - access("PAR"."ID"=TO_NUMBER(:VAL))
   7 - access("CHILD"."PAR_ID" IS NULL)
       filter(LNNVL("CHILD"."PAR_ID"="PAR"."ID"))
Note
-----
   - dynamic sampling used for this statement
 
27 rows selected
 
SQL>




--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
setnull
Дата 16.6.2009, 14:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 417
Регистрация: 3.7.2007

Репутация: 1
Всего: 1



 smile 
Пример работает
Делаю все точно так же!!!!
В моей таблице - FULLL!!!!


Может еще нужно планы как-то инвалиднуть?
PM MAIL   Вверх
Zloxa
Дата 16.6.2009, 15:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3473
Регистрация: 12.9.2008

Репутация: 37
Всего: 161



может для твоего случая фуллскан эффективнее? smile)
Для примера я специально выбирал именно такое сочетание данных чтобы на моем окружении индексный доступ  был эффективнее.

Добавлено через 45 секунд
Статистику после индексирования собирал?


--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
setnull
Дата 16.6.2009, 15:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 417
Регистрация: 3.7.2007

Репутация: 1
Всего: 1



Собирать - это строить или смотреть?
как это сделать?
PM MAIL   Вверх
Zloxa
Дата 16.6.2009, 15:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3473
Регистрация: 12.9.2008

Репутация: 37
Всего: 161





--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
setnull
Дата 18.6.2009, 10:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 417
Регистрация: 3.7.2007

Репутация: 1
Всего: 1



Цитата(Zloxa @ 16.6.2009,  15:26)
может для твоего случая фуллскан эффективнее? smile)
Для примера я специально выбирал именно такое сочетание данных чтобы на моем окружении индексный доступ  был эффективнее.

Статистику еще не собирал...
Но у меня возник вопрос. Это сарказм, или такое действительно может быть, что полное сканирование эффективнее?

Делаю выборку по значению -  индексирует
По is null - индексирует

по значению или is null - full scan, при этом выбираются 18,33% записей
PM MAIL   Вверх
DimW
Дата 18.6.2009, 10:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1330
Регистрация: 24.2.2005
Где: Орёл

Репутация: 23
Всего: 44



Цитата(setnull @  18.6.2009,  10:03 Найти цитируемый пост)
Это сарказм, или такое действительно может быть, что полное сканирование эффективнее?

Цитата(setnull @  18.6.2009,  10:03 Найти цитируемый пост)
по значению или is null - full scan, при этом выбираются 18,33% записей 

если 18% от 1000 записей в таблице, то скорей всего так и есть. если их все же на порядок больше, то можно предположить что оптимайзер об этом незнает, в этом случае стоит собрать статистику, а потом разбираться.
PM MAIL ICQ   Вверх
Zloxa
Дата 18.6.2009, 11:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3473
Регистрация: 12.9.2008

Репутация: 37
Всего: 161



Цитата(setnull @  18.6.2009,  10:03 Найти цитируемый пост)
Это сарказм, или такое действительно может быть, что полное сканирование эффективнее?

Это не сарказм.

При принятии решения о том, что выгоднее - фуллскан+хэш джойн или нестед луп +  доступ по индексу учитывается очень большое количества параметров. Как то: количество блоков в таблице, стоимость операции многблочного чтения, стоимость одноблочного чтения, кластеризация индекса, отношение стоимостей IO и CPU...

Мой опыт показывает, что я ошибаюсь в своем представлении об эффективности плана намного чаще чем оптимизатор при наличии достоверной статистики. Самостоятельно влиять на план выполнения приходится только тогда, когда я заведомо знаю больше оптимизатора. При этом, до сих пор в продуктивных решениях мне удавалось обходиться лишь двумя хинтами - first_rows & cardinality. При том, оба эти хинта - хинты оптимизатора.

Добавлено @ 11:27
Цитата(setnull @  18.6.2009,  10:03 Найти цитируемый пост)
по значению или is null - full scan, при этом выбираются 18,33% записей 

Следует учитывать что оптимизатор смотрит на значение при расчете селективности, только в сулчае, если это значение присутсвтует в гистограмме, в противном случае он принимает за селективность количество уникальных/ количество всего.
Как в этом случае будет оцениваться Null, мне не известно.
Вообще,я уже говорил что исползование null как значения - дурная практика, со всеми вытекающими. Null таки это "отсутствие значения"

Это сообщение отредактировал(а) Zloxa - 18.6.2009, 11:44


--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
v2v
Дата 19.6.2009, 13:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1620
Регистрация: 20.9.2006
Где: Киев

Репутация: 1
Всего: 56



У Тома Кайта видел пример сканирования по индеку при условии is (not) null, при том что не осуществляется сбор статистики.
Он предлагает индексировать не колонку, а функцию:  nvl(НАЗВАНИЕ_КОЛОНКИ,АЛЬТЕРНАТИВНОЕ_ЗНАЧЕНИЕ) .
Я попробовал воспроизвести такой пример, но без дополнительной хинтовки, он всё равно делает селект без индекса:
Код

create table t1(f1 number, f2 number);
alter table t1 add constraint t1#pk primary key(f1);

create index t1#i1 on t1 (nvl(f2,-1));

select /*+index(t1 t1#i1)*/* from t1 where nvl(f2,-1) = nvl(:a,-1);



--------------------
PM   Вверх
Zloxa
Дата 19.6.2009, 14:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3473
Регистрация: 12.9.2008

Репутация: 37
Всего: 161



Цитата(v2v @  19.6.2009,  13:59 Найти цитируемый пост)
Я попробовал воспроизвести такой пример, но без дополнительной хинтовки, он всё равно делает селект без индекса:

Для твоего примера у меня индекс используется и без хинта и без статистики (10.2.0.3, 9.2.0.8).
Однако отбор - это отбор.

А ты вот попробуй join по FBI сделать smile
У меня лично не получилось. Как грится хинтуй - не хинтуй, а в плане один .... smile)

Это сообщение отредактировал(а) Zloxa - 19.6.2009, 14:38


--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
Zloxa
Дата 19.6.2009, 15:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3473
Регистрация: 12.9.2008

Репутация: 37
Всего: 161



Цитата(Zloxa @  19.6.2009,  14:35 Найти цитируемый пост)
У меня лично не получилось

Гоню...
получилось ;)
Код

Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 
 
create table par(id primary key check (id != -1)) as select level from dual connect by level <=1e5;
 
Table created
create table child(id primary key,par_id) as select level,decode(mod(level,1e5),0,cast(null as number),mod(level,1e5)+1) from dual connect by level <= 1e6;
 
Table created
create index child$par_id$fbi on child (nvl(par_id,-1));
 
Index created
analyze table par compute statistics;
 
Table analyzed
analyze table child compute statistics for all columns;
 
Table analyzed
explain plan for
 select
   *
   from par
   inner join child on nvl(child.par_id, -1) in(par.id,-1)
 where par.id = :val;
 
Explained
select * from table(dbms_xplan.display);
 
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 158516727
--------------------------------------------------------------------------------
| Id  | Operation                         | Name             | Rows  | Bytes | C
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                  |                  |    32 |   384 |
|   1 |  NESTED LOOPS                     |                  |    32 |   384 |
|*  2 |   INDEX UNIQUE SCAN               | SYS_C0034125     |     1 |     4 |
|   3 |   TABLE ACCESS BY INDEX ROWID     | CHILD            |    32 |   256 |
|   4 |    BITMAP CONVERSION TO ROWIDS    |                  |       |       |
|   5 |     BITMAP OR                     |                  |       |       |
|   6 |      BITMAP CONVERSION FROM ROWIDS|                  |       |       |
|*  7 |       INDEX RANGE SCAN            | CHILD$PAR_ID$FBI |       |       |
|   8 |      BITMAP CONVERSION FROM ROWIDS|                  |       |       |
|*  9 |       INDEX RANGE SCAN            | CHILD$PAR_ID$FBI |       |       |
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
 
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
   2 - access("PAR"."ID"=TO_NUMBER(:VAL))
   7 - access("PAR"."ID"=NVL("PAR_ID",(-1)))
   9 - access(NVL("PAR_ID",(-1))=(-1))
Note
-----
   - dynamic sampling used for this statement
 
27 rows selected
 



--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
v2v
Дата 19.6.2009, 18:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1620
Регистрация: 20.9.2006
Где: Киев

Репутация: 1
Всего: 56



Цитата(Zloxa @  19.6.2009,  14:35 Найти цитируемый пост)

Для твоего примера у меня индекс используется и без хинта и без статистики (10.2.0.3, 9.2.0.8).

10.2.0.4 - фул скан и ничего не могу поделать.

Добавлено @ 18:07
Цитата(Zloxa @  19.6.2009,  15:11 Найти цитируемый пост)
Index created
analyze table par compute statistics;

но если со статитикой , как  у тебя по джойну то получается ...

Это сообщение отредактировал(а) v2v - 19.6.2009, 18:07


--------------------
PM   Вверх
setnull
Дата 23.6.2009, 13:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 417
Регистрация: 3.7.2007

Репутация: 1
Всего: 1



Код

inner join child on nvl(child.par_id, -1) in(par.id,-1)

я такое, если не ошибаюсь, поробовал раньше. При это в плане это разивается на два условия

nvl(child.par_id, -1) = par.id
or nvl(child.par_id, -1) =-1

но при этом все равно остается фулскан...

Цитата

analyze table par compute statistics;
analyze table child compute statistics for all columns;


Это директивы или консольный вывод?

И вообще, где можно достать полезную информацию о механизмах планирования и оптимизации. Все, с чем я сталкивался до этого -  очень общие понятия (Оракл делает планы, и потом ими пользуется). Но при этом я не имею целостного представления о том, что, где и когда делает Оракл? Что, где и когда может анализировать разработчик, а также чем, где и когда он может пользоваться, чтоб работа всего этого механизма происходила эффективно ?


Спасибо!!!
PM MAIL   Вверх
Zloxa
Дата 23.6.2009, 13:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3473
Регистрация: 12.9.2008

Репутация: 37
Всего: 161



Цитата(setnull @  23.6.2009,  13:00 Найти цитируемый пост)
И вообще, где можно достать полезную информацию о механизмах планирования и оптимизации.

Oracle® Database Performance Tuning Guide
Цитата(setnull @  23.6.2009,  13:00 Найти цитируемый пост)
Это директивы или консольный вывод?

ANALYZE
Цитата

Note:
Do not use the COMPUTE and ESTIMATE clauses of ANALYZE to collect optimizer statistics. These clauses are supported for backward compatibility. Instead, use the DBMS_STATS package, which lets you collect statistics in parallel, collect global statistics for partitioned objects, and fine tune your statistics collection in other ways.

Цитата(setnull @  23.6.2009,  13:00 Найти цитируемый пост)
поробовал раньше.

1)Индекс по функции при том строил?
2)Статистика по индексу,(таблице) после построения индекса собиралась?
3)Системная статистика вообще когданибудь собиралась?
Цитата(setnull @  23.6.2009,  13:00 Найти цитируемый пост)
но при этом все равно остается фулскан...

4)Ты уверен в том что фуллскан МЕНЕЕ эффективен?
Случается, порой, я ПРИНУЖДАЮ ораклю использовать full scan, потому как дождаться результата при использовании индексного доступа - терпения не хватает. Ты упоминал ранее что селективность твоего запроса 18%. Это достаточно высокая селективность. На такой селективности я вполне могу поверить что фуллскан будет эффективнее. Все зависит от отношения стоимости операций ввода вывода к стоимости операций CPU. Может так статься что сотни многоблочных чтений с полной загрузкой ЦПУ будут выполняться много быстрее тысяч одноблочных чтений при низкой загурзке ЦПУ.

если ответы на вопросы 1,2,3,4 утвердительные, используй хинт INDEX, как это делает v2v в своем примере.


Это сообщение отредактировал(а) Zloxa - 23.6.2009, 14:35


--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
setnull
Дата 23.6.2009, 15:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 417
Регистрация: 3.7.2007

Репутация: 1
Всего: 1



Спаисбо за сылки!

1) - да. Разве что, я использовал выражение (как в индексе, так и в запросе) DECODE(FILED, null, 0, FILED). Это же не принципиально?
2) и 3) Скорей всего нет, если это не делается автоматически
4) Ничего не могу сказать вообще...

Т.е. буду читать теорию...
Только еще хочу уточнить, приведенные ссылки могут дать понимание на уровне

Цитата

Все зависит от отношения стоимости операций ввода вывода к стоимости операций CPU. Может так статься что сотни многоблочных чтений с полной загрузкой ЦПУ будут выполняться много быстрее тысяч одноблочных чтений при низкой загурзке ЦПУ.


Или до этого еще очень далеко?
PM MAIL   Вверх
Zloxa
Дата 23.6.2009, 15:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3473
Регистрация: 12.9.2008

Репутация: 37
Всего: 161



1) Нет, не принципиально.

4) Дык а попробовать? smile))

Цитата(setnull @  23.6.2009,  15:15 Найти цитируемый пост)
дать понимание на уровне

Указанный уровень весьма абстрактен. smile)
Многие хвалят книгу Льюиса "Основы стоимостной оптимизации". Я читал лишь пару глав... (кста, надо найти и перечесть smile). Кашу в мозгах сортирует хорошо. Но особого прозрения не ожидай, там лишь описано как, почему и на основе чего оптимизатор выбирает план. Однако что именно дает понимание этого, ясно весьма не сразу. ;) Понимание принципов работы оптимизатора приводит лишь к тому что начинаешь чаще соглашаться с результатами его работы smile


Это сообщение отредактировал(а) Zloxa - 23.6.2009, 17:29


--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Oracle"
Zloxa
LSD

Данный раздел предназначен для обсуждения проблем с Oracle Database, другие продукты Oracle здесь не обсуждаются. Просьба при создании темы, придерживаться следующих правил:

  • при создании темы давайте ей осмысленное название, описывающее суть проблемы
  • указывайте используемую версию базы, способ соединения и язык программирования
  • при ошибках обязательно приводите код ошибки и сообщение сервера
  • приводите код в котором возникла ошибка, по возможности дайте тестовый пример демонстрирующий ошибку
  • при вставке кода используйте соответсвующие теги: [code=sql] [/code] для подсветки SQL и PL/SQL кода, [code=java] [/code] - для Java, и т.д.

  • документация по Oracle: 9i, 10g, 11g
  • книги по Oracle можно поискать здесь
  • действия модераторов можно обсудить здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Zloxa, LSD.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Oracle | Следующая тема »


 




[ Время генерации скрипта: 0.0832 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.