Pull to refresh

Comments 22

Спасибо, отличная статья!
Хотя трудно придумать все-таки хоть один реальный пример где MODEL была бы нужна. Было бы интересно если бы вы написали какой-нибудь запрос на котором MODEL быстрее PL/SQL -ной реализации хотя бы в 2 раза.
Для аналитики, где же еще?? :)
Тут вопрос не в том что это более производительно, тут скорее вопрос гибкости.
и да и нет. В пл/сиквеле если большая выборка и сложная аналитика придется создавать временные таблицы, что само по себе не плохо, но это лишний объект.
а тут вопрос одного селекта.
Временные таблицы создают те, кто перешел в Oracle из MS-SQL. В Oracle почти никогда нет необходимости во временных таблицах в коде. Вполне можно обойтись курсорами и коллекциями.

«В пл/сиквеле если большая выборка „

От размера выборки вообще не зависит.

“ что само по себе не плохо, но это лишний объект. „

Еще один бред. Кому он лишний? Как будто интерпретатор sql не создает временных объектов при выполнении запроса. Еще неизвестно какой объект будет больше по размеру и тормознутее — универсальный, или созданный в коде специально для этой задачи.
я никогда не использовал MSSQL, это так для справки :)

но временные таблицы Оракле существуют не просто так, если бы все было как вы говорите их бы скорее всего даже и не было.

Я говорил о большой «выборке и сложной аналитике» давайте уже если придераться к словам то не выдерать их из конкеста.
В каких случаях можно а иногда и нужно использовать global temporary table.

предстваим на секунду отчет
представляющий объединения трех селектов, каждый из которых сам по сибе очень тяжол, и это так не потому что код неоптимаоен а лишь потому что к примеру это годовой отчет Нумерующего агенства целой республики и речь идет об анализе и посчете неких значнеий на основании миллиардов строк…

т.е. появляется два варианта, либо селект вида:
select some calculations from (select some hard calculations from t1,t2,t3 where bla-bla group by blabla ),
(select some hard calculations from t4,t5,t6 where bla-bla group by blabla ),
(select some hard calculations from t7,t8,t9 where bla-bla group by blabla )
group by cube (bla-bla)

как можно видедь из примера для отчета необходимо подсчитать три набора данных, кторые и по отдельности считаются не секунды.
а их объединеие и подавно а плюс ко всему еще и групировка всех вариантов. для подсчета промежуточных итогов. представляете сибе план такого запроса?? :)

либо вариант два испольнить внутрение селекты по отдельности заинсертить эти занчение в три глобальные таблицы, а уже после соединить и с агрегировать. для этого как вы понимаете придется использовать pl/sql процедуру.

Вариант два будет как правило предпочтительнее.

что качсается слова лишний согласен, давайте заменим его на дополнительный :)) и оставим эту тему ок? :)
кстати модели в таком случае тоже не спасут :)) это я уже скорее к применению global temporary table исключительно :))
«либо вариант два испольнить внутрение селекты по отдельности заинсертить эти занчение в три глобальные таблицы, а уже после соединить и с агрегировать. для этого как вы понимаете придется использовать pl/sql процедуру.

Вариант два будет как правило предпочтительнее. „

Во-первых, пишите чуть-чуть грамотней, тяжело читать, но это так, придирки.
Во-вторых, что-то я вас не понимаю. С чего это он будет предпочтительней? Вы думаете вы сами соедините эти таблицы лучше чем ядро SQL? Ошибаетесь. Производительность у вашего горе-решения с временными таблицами будет намного хуже, можете проверить на практике и убедиться.
Так что ваш пример — полностью fail.

Холиварить не хочется, к тому же ситуация может меняться, от случая к случаю.

Но в случае большого набора данных, и сложных вычислений, приходится в конце создать временные таблицы, хотя я сам стараюсь до последнего это не делать.
И да, слава богу, я буду лучше знать как исполнять запрос. Иначе бы мой работодатель уволил меня, дорогостоящего Ораклоида, нанял бы студента с минимальными знаниями SQL-92, а оптимизатор тюнил бы за него запросы.

Вера в великий и могучий оптимизатор конечно хорошо, но он ошибается.

а вот примерчик. У меня первый скульный вариант даже не отработал ;)
Почему все просто, любой курсор будет размещен в buffer cache, а его как я проиллюстрировал может и не хватить.
А вот временные таблицы находятся temporary tablespace и запрос легко отрабатывает ;)
CREATE global TEMPORARY TABLE xxx1 (c1 VARCHAR2 (1), c2 NUMBER) ON COMMIT
DELETE rows;
/
CREATE global TEMPORARY TABLE xxx2 (c1 VARCHAR2 (1), c2 NUMBER) ON COMMIT
DELETE rows;
/
CREATE TABLE xxx3
(c1 VARCHAR2 (1), c2 NUMBER
) ;
/
BEGIN
INSERT INTO xxx1
SELECT 'V' c1, LEVEL c2 FROM dual CONNECT BY level < 10000000;
INSERT INTO xxx2
SELECT 'D' c1, LEVEL c2 FROM dual CONNECT BY level < 10000000;
INSERT INTO xxx3
SELECT t1.c1, t2.c2 FROM xxx1 t1, xxx2 t2 WHERE t1.c2 = t2.c2;
END;
/

ой забыл собственно SQL вариант
INSERT INTO xxx3
SELECT t1.c1, t2.c2
FROM
(SELECT 'V' c1, LEVEL c2 FROM dual CONNECT BY level < 10000000
) t1, (SELECT 'D' c1, LEVEL c2 FROM dual CONNECT BY level < 10000000
) t2
WHERE t1.c2 = t2.c2;
самое правильное гармонично сочетать скул и пл/скуель.

к тому же есть миф заражденный Кайтом: «Если вы можете решить задачу одним скул оператором, решите ее им, это будет быстрее», как правило так и есть, но иногда запрос легче разбить, проинсертить во временные таблички, а уже потом это анализировать…
Это называется «денормализация».
денормализация отностися скорее к структуре данных, т.е. к хранению данных, то о чем я говорю отностися к выборке.
Т.е. структура данных может быть «нормальной» но отчет требует анализа большого количества данных и применения ВРЕМЕННЫХ таблиц, для оптимизации скорости выполнения, но они по суте не являются хранилищем в привычном смысле, так как данные храняться до тех пор пока нужны и не более того. и не попадают в табличные пространства с данными приложения, а хранятся в специально отведенном временном табличном пространстве.

где-то так.
А как на скорость выборок влияют представления?
зависит от представлений, если вопрос в том стоит ли использовать view то ответ однозначно да!

Вьюв имеют два преимущества они позволяют однажды написать селект к некторой сущности и потом его использовать всегда. Сразу же оговорюсь всегда нужно понимать что ты делаешь. К примеру если во вьев декодируются значения неких Id на основе справочников, путем JOIN'а этих таблиц, то при условии того, что это соединение не влияет на кардинальность выборки, Count(*) лучше считать от таблицы. Это в случае join, с случае если поля декодируются подзапросом без разницы Cost-based оптимизатор не будет исполнять подзапрос при подстчете count(*), так как подзапросом на кардинальность выборки по определению не повлияешь.

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

Надеюсь помог.
Спасибо. познавательно.
Только нужно учесть, что при анализе представлений, использующих представления, оптимизатор бывает начинает глючить, и он не может выбрать правильный план запроса. Т.е. в сложной иерархии
представлений можно потерять производительность если не обращать на это внимание.
Денормализация (англ. denormalization) — намеренное приведение структуры базы данных в состояние, не соответствующее критериям нормализации, обычно проводимое с целью ускорения операций чтения из базы за счет добавления избыточных данных. Денормализация — это избирательное хранение избыточной информации в базе данных.

Ничего нет про временное или постоянное.
Достаточно сравнить pivot'ы, реализованные на PL/SQL и на MODEL. Хотя о такой разнице в быстродействии речь всё равно не идёт.
Так есть же уже оператор pivot, он будет еще быстрее.
Большинство всё ещё на десятке, и не думает обновляться :)
А многие еще и на 9ке, там даже model нет :)
Sign up to leave a comment.

Articles