![]() |
|
Модераторы: LSD, AntonSaburov |
![]()
|
|
| Sun |
|
|||
|
Account removed ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 1611 Регистрация: 14.8.2002 Репутация: 2 Всего: 48 |
boroda, привел текст процедуры в котором был следующий вызов
В приведенной мной цитате вы советуете заменить вызовы хранимых процедур прямым вызовом SQL запроса. Следуя из контекста темы, запрос должен вызываться из Java кода, то есть извне. Далее следует фраза "Мало того, что это будет переносимое решение, но оно так же обычно оказывается лучше по производительности" из чего я делаю логический вывод что вы считаете хранимые процедуры менее эффективными чем вызовы внешних SQL запросов. Дальше по моей просьбе вы приводите доказательство своей мысли. Я ставлю его под сомнение, так как мне непонятно почему "Заменяя подзапросы вызовами хранимых процедур вы лишите оптимизатор возможности выбора стратегии.". Дальше мы приходим к выводу что вызов SQL запроса происходит практически одинаково как из хранимой процедуры, так и из внешнего приложения. На основе этого я делаю утверждение, что вы признали, что внешние SQL запросы не могут быть лучшими по производительности, чем хранимые процедуры -------------------- Account removed |
|||
|
||||
| 3x3 |
|
||||||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 261 Регистрация: 17.9.2006 Репутация: 5 Всего: 8 |
Да, естественно. У процедур, конечно, есть своя роль в жини, но она не заключается в подмене частей обычных SQL-выражений.
Это может вытечь разве из соображений переносимости, вряд ли из контекста.
Я начинаю вас понимать Вы немножко забываете о том, что кроме отработки вызова, серверу ещё нужно сделать некоторую полезную работу. Я не думаю, что вы мне приведёте пример базы данных, в которой времени на отработку собственно вызов тратится больше, чем на работу - такая система просто не смогла бы работать постоянно с полной нагрузкой, периодически уходя в отказ в обслуживании при переполнении очереди вызовов, да в случаях когда время обращения к серверу критично - используются более другие решения: прямая загрузка данных в базу в обход ограничений целостности, кеширование огромных объемов данных на сервере приложений и т.п. PS Кстати, с точки зрения сопровождения БД 24х7 будет любопытно взглянуть как вы в работающей базе будете при необходимости апдейтить две функции, из которых одна вызывает другую - ну мало ли что там поменялось ;) PPS А у вас аватар не просто так выбран? По SunOS можно обратиться с вопросиком? Это сообщение отредактировал(а) 3x3 - 2.10.2006, 22:40 -------------------- Зачем платить больше, когда можно заплатить дважды? |
||||||||
|
|||||||||
| 3x3 |
|
||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 261 Регистрация: 17.9.2006 Репутация: 5 Всего: 8 |
Вобщем, проверил на практике. Начерно, конечно, но меня устраивает
А кому не нравятся мои результаты - могут опровергать своими, код приведен. База:
Вызывающий код:
Как видим, четыре разных запроса по-разному вставляют строку: 0: insert into xtest select ?, c_id from xcountry where c_name=? - простой запрос, который я рекомендовал 1: insert into xtest values(?, xget_country_id(?)) - запрос извлекающий ИД страны вызовом функции 2: call xinsert_test(?,?) - процедура, идущая по пути автора треда и вызывающая функцию для получения ИДа 3: call xinsert_test2(?,?) - Такой же запрос, как и в случае 0, только зачем-то упакованный в процедуру Результат теста: При включенном автокоммите: Test started for 1000 rows per pass Pass 0 query 0 passed for 26438 ms Pass 0 query 1 passed for 29344 ms Pass 0 query 2 passed for 30265 ms Pass 0 query 3 passed for 28360 ms Pass 1 query 0 passed for 27109 ms Pass 1 query 1 passed for 30047 ms Pass 1 query 2 passed for 30172 ms Pass 1 query 3 passed for 28015 ms Pass 2 query 0 passed for 28875 ms Pass 2 query 1 passed for 30125 ms Pass 2 query 2 passed for 29797 ms Pass 2 query 3 passed for 27172 ms Pass 3 query 0 passed for 30344 ms Pass 3 query 1 passed for 30141 ms Pass 3 query 2 passed for 29218 ms Pass 3 query 3 passed for 27860 ms Test finished Выключаю автокоммит Test started for 1000 rows per pass Pass 0 query 0 passed for 281 ms Pass 0 query 1 passed for 187 ms Pass 0 query 2 passed for 188 ms Pass 0 query 3 passed for 172 ms Pass 1 query 0 passed for 140 ms Pass 1 query 1 passed for 172 ms Pass 1 query 2 passed for 188 ms Pass 1 query 3 passed for 156 ms Pass 2 query 0 passed for 156 ms Pass 2 query 1 passed for 157 ms Pass 2 query 2 passed for 203 ms Pass 2 query 3 passed for 156 ms Pass 3 query 0 passed for 156 ms Pass 3 query 1 passed for 406 ms Pass 3 query 2 passed for 235 ms Pass 3 query 3 passed for 156 ms Test finished Быстровато, увеличил количество инсертов Test started for 100000 rows per pass Pass 0 query 0 passed for 12046 ms Pass 0 query 1 passed for 12563 ms Pass 0 query 2 passed for 13812 ms Pass 0 query 3 passed for 12703 ms Pass 1 query 0 passed for 11953 ms Pass 1 query 1 passed for 12907 ms Pass 1 query 2 passed for 16171 ms Pass 1 query 3 passed for 12891 ms Pass 2 query 0 passed for 12125 ms Pass 2 query 1 passed for 12891 ms Pass 2 query 2 passed for 16093 ms Pass 2 query 3 passed for 13047 ms Pass 3 query 0 passed for 11657 ms Pass 3 query 1 passed for 13203 ms Pass 3 query 2 passed for 15968 ms Pass 3 query 3 passed for 13032 ms Test finished Добавил DETERMINISTIC в определение функции Test started for 100000 rows per pass Pass 0 query 0 passed for 11875 ms Pass 0 query 1 passed for 12594 ms Pass 0 query 2 passed for 13812 ms Pass 0 query 3 passed for 12922 ms Pass 1 query 0 passed for 11766 ms Pass 1 query 1 passed for 12906 ms Pass 1 query 2 passed for 14406 ms Pass 1 query 3 passed for 12781 ms Pass 2 query 0 passed for 11828 ms Pass 2 query 1 passed for 13032 ms Pass 2 query 2 passed for 16297 ms Pass 2 query 3 passed for 12421 ms Pass 3 query 0 passed for 12141 ms Pass 3 query 1 passed for 13156 ms Pass 3 query 2 passed for 14266 ms Pass 3 query 3 passed for 12844 ms Test finished ЧТД PS На всякий случай, статус базы: SSL: Not in use Using delimiter: ; Server version: 5.0.22-community-max-nt Protocol version: 10 Connection: localhost via TCP/IP Server characterset: utf8 Db characterset: utf8 Client characterset: utf8 Conn. characterset: utf8 TCP port: 3306 Uptime: 23 hours 36 min 42 sec Это сообщение отредактировал(а) 3x3 - 3.10.2006, 03:34 -------------------- Зачем платить больше, когда можно заплатить дважды? |
||||
|
|||||
| Sun |
|
||||
|
Account removed ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 1611 Регистрация: 14.8.2002 Репутация: 2 Всего: 48 |
Можно, правда я с ней не работал Что касается приведенного кода - я наконец-то понял к чему вы клоните. То-есть вы ничего не имеете против самих хранимых процедур, вы просто против их вызова в теле запроса и говорите что использовать вложенные запросы гораздо эффективнее. С этим спорить не буду, так как не проводил бэнчмарков по сабжу. Единственно добавлю что вложенных запросов также стоит избегать, а по возможности использовать JOIN.
-------------------- Account removed |
||||
|
|||||
| 3x3 |
|
||||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 261 Регистрация: 17.9.2006 Репутация: 5 Всего: 8 |
А, ну ладно тогда, я в соответствующем разделе спросил..
Поздравляю. Утро вечера мудренее.
Не люблю этот синтаксис, и не знаю что он такого даёт в повседневном использовании. Мне больше нравится когда таблицы в запросе рядом через запятую перечислены -------------------- Зачем платить больше, когда можно заплатить дважды? |
||||||
|
|||||||
| Sun |
|
|||
|
Account removed ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 1611 Регистрация: 14.8.2002 Репутация: 2 Всего: 48 |
Такой запрос отрабатывает более быстро чем если вы укажите через запятую или как вложенный запрос. -------------------- Account removed |
|||
|
||||
| boroda |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 29 Регистрация: 2.12.2005 Где: Киев Репутация: 1 Всего: 1 |
Спасибо всем. Но в данном случае я не могу отказаться от процедур. Опять вопрос у меня был не в том что лучше, а что хуже. Вопрос был почему так работает а этак не работает. Но всеравно спасибо, было действительно интересно
|
|||
|
||||
| 3x3 |
|
||||||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 261 Регистрация: 17.9.2006 Репутация: 5 Всего: 8 |
Вот только вопрос - почему? Я вижу только одну потенциальную причину - это то, что в запросе вы явно задаёте оптимизатору по какому набору данных осуществлять внешний цикл, а по каким - вложенные. Т.е. в общем случае выигрыш должен быть на RDBMS, с оптимизатором, ничего не знающим про свои данные и, соответственно, неспособным полноценно оптимизировать план запроса? Добавлено @ 12:04
Работающие процедуры приведены в коде бенчмарка.. Я бы на вашем месте их бенчмарком у себя и тестировал. Там, возможно, и у вас не null возвращается, а исключение. Там какие-то грабли с разграничением полномочий мне повстречались.
Ну теперь мне уже и самому интересно стало -------------------- Зачем платить больше, когда можно заплатить дважды? |
||||||||
|
|||||||||
| Sun |
|
|||
|
Account removed ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 1611 Регистрация: 14.8.2002 Репутация: 2 Всего: 48 |
Нельзя слишком доверять оптимизаторам. Как показывает практика, запросы с перечисленными через запятую таблицами отрабатывают медленней и уж тем более вложенные запросы, чем объединенные через JOIN. Особенно на больших объёмах. -------------------- Account removed |
|||
|
||||
![]()
|
| Правила форума "Java" | |
|
|
Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Java EE (J2EE) и Spring | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |