Перекомпиляция плана

PaulWist
Дата: 03.03.2022 15:44:42
Если на таблице построить индекс приведёт ли это к перекомпиляции плана?

-- табличка
create table test (f1 varchar2);
-- генерим план
var v1 varchar2;
exec :v1 := '1';
select * from test where f1 = :v1;
-- индекс
create index idx on test (f1);
-- будет ли построен новый план??
var v1 varchar2;
exec :v1 := '1';
select * from test where f1 = :v1;
Leonid Kudryavtsev
Дата: 03.03.2022 16:54:51
Что такое перекомпиляция плана?
Первый раз такое слышу.

Команд CREATE PLAN IS и ALTER PLAN RECOMPILE - лично я не знаю.

Знаю только слова Parse, Execute, Fetch )))
Master_Detail
Дата: 03.03.2022 17:46:32
PaulWist
приведёт ли это к перекомпиляции плана?

Картинка с другого сайта.
А почему бы все же не проверить?

Но если хотите простой ответ - конечно же, план может перекомпилиться измениться. А может и не измениться, потому как есть еще распределение данных, селективность и все такое прочее

-- генерим план
var v1 varchar2;
exec :v1 := '1';
select * from test where f1 = :v1;

Можете подробнее рассказать про то, как вы "генерите" план. Думаю, многие на форуме не знают про эту фичу
PaulWist
Дата: 04.03.2022 10:57:16
Master_Detail


А почему бы все же не проверить?


Проверил.

Master_Detail


Но если хотите простой ответ - конечно же, план может перекомпилиться измениться. А может и не измениться, потому как есть еще распределение данных, селективность и все такое прочее


ОК, план изменился, начал использовать новый индекс.

Кстати, как заставить принудительно перекомпилировать изменять план при bind параметрах?? (например в MSSQL используется опция RECOMPILE), то есть для одного SQL_ID получить несколько планов??

Master_Detail


-- генерим план
var v1 varchar2;
exec :v1 := '1';
select * from test where f1 = :v1;

Можете подробнее рассказать про то, как вы "генерите" план. Думаю, многие на форуме не знают про эту фичу


Пожалуйста, всё очень просто :)

select * from test where f1 = '1';

select * from test where f1 = '2';


Вызовет создание 2-х планов.
PaulWist
Дата: 04.03.2022 10:58:28
Leonid Kudryavtsev,

Неудачно выразился, создание нового плана для одного и того же запроса.
Asmodeus
Дата: 04.03.2022 11:44:27
PaulWist,

Принудительно инвалидировать курсоры (инициировав жесткий разбор (hard parse) запросов с возможным(!) построением новых планов, в которых задействованы объекты БД) можно через сбор статистики по объекту с помощью пакета DBMS_STATS (опция no_invalidate). Начиная с версии 11.2 (если я правильно помню), можно удалить планы для конкретного запроса из shared pool используя пакет DBMS_SHARED_POOL, что также инициирует жесткий разбор и возможное построение нового плана.

ЗЫ: инвалидировать курсоры в оракле можно и достаточно безобидными DDL (типа comment).
ЗЗЫ: в проде так делать надо очень осторожно.
Asmodeus
Дата: 04.03.2022 11:47:32
PaulWist

select * from test where f1 = '1';

select * from test where f1 = '2';


Вызовет создание 2-х планов.
В зависимости от значения параметра cursor_sharing.
PaulWist
Дата: 04.03.2022 11:51:52
Asmodeus
PaulWist


Вызовет создание 2-х планов.
В зависимости от значения параметра cursor_sharing.


Ну, ОК.

select * from test where f1 = '1' and 1 = 1;

select * from test where f1 = '2' and 2 = 2;
istrebitel
Дата: 04.03.2022 11:58:46
А разве не то же самое?
Asmodeus
Дата: 04.03.2022 12:02:36
PaulWist
Asmodeus
пропущено...
В зависимости от значения параметра cursor_sharing.


Ну, ОК.

select * from test where f1 = '1' and 1 = 1;

select * from test where f1 = '2' and 2 = 2;
У них sql_id одинаковый? :)