Комментарии 22
Спасибо, отличная статья!
Хотя трудно придумать все-таки хоть один реальный пример где MODEL была бы нужна. Было бы интересно если бы вы написали какой-нибудь запрос на котором MODEL быстрее PL/SQL -ной реализации хотя бы в 2 раза.
Хотя трудно придумать все-таки хоть один реальный пример где MODEL была бы нужна. Было бы интересно если бы вы написали какой-нибудь запрос на котором MODEL быстрее PL/SQL -ной реализации хотя бы в 2 раза.
Для аналитики, где же еще?? :)
Тут вопрос не в том что это более производительно, тут скорее вопрос гибкости.
Тут вопрос не в том что это более производительно, тут скорее вопрос гибкости.
Ну так ведь pl/sql еще гибче.
и да и нет. В пл/сиквеле если большая выборка и сложная аналитика придется создавать временные таблицы, что само по себе не плохо, но это лишний объект.
а тут вопрос одного селекта.
а тут вопрос одного селекта.
Временные таблицы создают те, кто перешел в Oracle из MS-SQL. В Oracle почти никогда нет необходимости во временных таблицах в коде. Вполне можно обойтись курсорами и коллекциями.
«В пл/сиквеле если большая выборка „
От размера выборки вообще не зависит.
“ что само по себе не плохо, но это лишний объект. „
Еще один бред. Кому он лишний? Как будто интерпретатор sql не создает временных объектов при выполнении запроса. Еще неизвестно какой объект будет больше по размеру и тормознутее — универсальный, или созданный в коде специально для этой задачи.
«В пл/сиквеле если большая выборка „
От размера выборки вообще не зависит.
“ что само по себе не плохо, но это лишний объект. „
Еще один бред. Кому он лишний? Как будто интерпретатор 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.
предстваим на секунду отчет
представляющий объединения трех селектов, каждый из которых сам по сибе очень тяжол, и это так не потому что код неоптимаоен а лишь потому что к примеру это годовой отчет Нумерующего агенства целой республики и речь идет об анализе и посчете неких значнеий на основании миллиардов строк…
т.е. появляется два варианта, либо селект вида:
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? Ошибаетесь. Производительность у вашего горе-решения с временными таблицами будет намного хуже, можете проверить на практике и убедиться.
Так что ваш пример — полностью fail.
Холиварить не хочется, к тому же ситуация может меняться, от случая к случаю.
Но в случае большого набора данных, и сложных вычислений, приходится в конце создать временные таблицы, хотя я сам стараюсь до последнего это не делать.
И да, слава богу, я буду лучше знать как исполнять запрос. Иначе бы мой работодатель уволил меня, дорогостоящего Ораклоида, нанял бы студента с минимальными знаниями SQL-92, а оптимизатор тюнил бы за него запросы.
Вера в великий и могучий оптимизатор конечно хорошо, но он ошибается.
а вот примерчик. У меня первый скульный вариант даже не отработал ;)
Почему все просто, любой курсор будет размещен в buffer cache, а его как я проиллюстрировал может и не хватить.
А вот временные таблицы находятся temporary tablespace и запрос легко отрабатывает ;)
Но в случае большого набора данных, и сложных вычислений, приходится в конце создать временные таблицы, хотя я сам стараюсь до последнего это не делать.
И да, слава богу, я буду лучше знать как исполнять запрос. Иначе бы мой работодатель уволил меня, дорогостоящего Ораклоида, нанял бы студента с минимальными знаниями 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;
/
самое правильное гармонично сочетать скул и пл/скуель.
к тому же есть миф заражденный Кайтом: «Если вы можете решить задачу одним скул оператором, решите ее им, это будет быстрее», как правило так и есть, но иногда запрос легче разбить, проинсертить во временные таблички, а уже потом это анализировать…
к тому же есть миф заражденный Кайтом: «Если вы можете решить задачу одним скул оператором, решите ее им, это будет быстрее», как правило так и есть, но иногда запрос легче разбить, проинсертить во временные таблички, а уже потом это анализировать…
Это называется «денормализация».
денормализация отностися скорее к структуре данных, т.е. к хранению данных, то о чем я говорю отностися к выборке.
Т.е. структура данных может быть «нормальной» но отчет требует анализа большого количества данных и применения ВРЕМЕННЫХ таблиц, для оптимизации скорости выполнения, но они по суте не являются хранилищем в привычном смысле, так как данные храняться до тех пор пока нужны и не более того. и не попадают в табличные пространства с данными приложения, а хранятся в специально отведенном временном табличном пространстве.
где-то так.
Т.е. структура данных может быть «нормальной» но отчет требует анализа большого количества данных и применения ВРЕМЕННЫХ таблиц, для оптимизации скорости выполнения, но они по суте не являются хранилищем в привычном смысле, так как данные храняться до тех пор пока нужны и не более того. и не попадают в табличные пространства с данными приложения, а хранятся в специально отведенном временном табличном пространстве.
где-то так.
А как на скорость выборок влияют представления?
зависит от представлений, если вопрос в том стоит ли использовать view то ответ однозначно да!
Вьюв имеют два преимущества они позволяют однажды написать селект к некторой сущности и потом его использовать всегда. Сразу же оговорюсь всегда нужно понимать что ты делаешь. К примеру если во вьев декодируются значения неких Id на основе справочников, путем JOIN'а этих таблиц, то при условии того, что это соединение не влияет на кардинальность выборки, Count(*) лучше считать от таблицы. Это в случае join, с случае если поля декодируются подзапросом без разницы Cost-based оптимизатор не будет исполнять подзапрос при подстчете count(*), так как подзапросом на кардинальность выборки по определению не повлияешь.
А так же View позволяют ограничить доступ пользователей к данным, к примеру как правило не все пользователи должны видеть все строки таблицы.
Надеюсь помог.
Вьюв имеют два преимущества они позволяют однажды написать селект к некторой сущности и потом его использовать всегда. Сразу же оговорюсь всегда нужно понимать что ты делаешь. К примеру если во вьев декодируются значения неких Id на основе справочников, путем JOIN'а этих таблиц, то при условии того, что это соединение не влияет на кардинальность выборки, Count(*) лучше считать от таблицы. Это в случае join, с случае если поля декодируются подзапросом без разницы Cost-based оптимизатор не будет исполнять подзапрос при подстчете count(*), так как подзапросом на кардинальность выборки по определению не повлияешь.
А так же View позволяют ограничить доступ пользователей к данным, к примеру как правило не все пользователи должны видеть все строки таблицы.
Надеюсь помог.
Денормализация (англ. denormalization) — намеренное приведение структуры базы данных в состояние, не соответствующее критериям нормализации, обычно проводимое с целью ускорения операций чтения из базы за счет добавления избыточных данных. Денормализация — это избирательное хранение избыточной информации в базе данных.
Ничего нет про временное или постоянное.
Ничего нет про временное или постоянное.
Достаточно сравнить pivot'ы, реализованные на PL/SQL и на MODEL. Хотя о такой разнице в быстродействии речь всё равно не идёт.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Диалект Oracle SQL: Model в примерах. Часть 2