Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Эффективнось запуска SP из ADO
|
|||
|---|---|---|---|
|
#18+
Коллеги, Какой способ запуска Stored Procedure из ADO более эффективный и почему? 1. Cmd.ActiveConnection = cn Cmd.CommandType = adCmdStoredProc Cmd.CommandText = "my_cool_sp" Set rs = Cmd.Execute 2. Set Rs = Server.CreateObject("ADODB.Recordset") Set Rs.ActiveConnection = cn Rs.CursorType = adOpenStatic Rs.LockType = adLockReadOnly Rs.Source = "exec my_cool_sp" Rs.Open ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.10.2001, 02:08 |
|
||
|
Эффективнось запуска SP из ADO
|
|||
|---|---|---|---|
|
#18+
Чего-то мне кажется, что все одинаково, только с помощью второго способа можно только рекордсет получить из процедуры, и то если в ней ничего ни куда не вставляется, а с помощью первого метода можно все что хочешь сделать, хоть параметры обратно получать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.10.2001, 06:39 |
|
||
|
Эффективнось запуска SP из ADO
|
|||
|---|---|---|---|
|
#18+
Правильнее поставить вопрос, в чем различие между такими вариантами: 1. Cmd.ActiveConnection = cn Cmd.CommandType = adCmdStoredProc Cmd.CommandText = "my_cool_sp" Set rs = Cmd.Execute 2. Cmd.ActiveConnection = cn Cmd.CommandType = adCmdText Cmd.CommandText = "exec my_cool_sp" Set rs = Cmd.Execute Твой второй вариант в дебрях ADO выполняет примерно то, что было бы выполнено по приведенному мной варианту 2. Задействуются одни и те же механизмы, только через разные двери. А вот разница между приведенными мной вариантами действительно есть, и она недавно была выявлена моим коллегой при работе с типами sql_variant MS SQL SERVER 2000. Если хранимая процедура использует параметры типа sql_variant, через который на сервер передается текстовая информация, то во втором варианте эта информация получае colation, назначенный как default colation для сервера и базы данных, а в первом случае colation силком проставляется внутренними механизмами ADO, который чаще всего не совпадает с collation всей остальной используемой в БД текстовой информации. Не совпадение collation при сравнении двух значений типа sql_variant приводит к невыполнению равенства, хотя текст содержит одну и ту же фразу (да еще на английском). Нам пришлось все вызовы первого типа заменить на вызовы второго типа, чтобы устранить проблемы с collation. Следует оговориться, что данные проблемы возникают ТОЛЬКО при использовании вариантных параметров. Для всех других типов параметров они не возникают. А насчет эффективности - IMHO те же шары, только в профиль. Возможно, имеются какая-то разница в скорости выполнения первого и второго кода, но обычно такой код не включают в в тело самого глубокого из пяти вложенных циклов, поэтому в основном эта разница значения существенной роли не играет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.10.2001, 06:51 |
|
||
|
Эффективнось запуска SP из ADO
|
|||
|---|---|---|---|
|
#18+
2 tygra Откуда такая информация, что по первому способу нельзя вызвать процедуру, если в ней что-то куда-то вставляется? Кроме оговоренной проблемы с Collation IMHO между ними вообще нет разницы. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.10.2001, 06:56 |
|
||
|
Эффективнось запуска SP из ADO
|
|||
|---|---|---|---|
|
#18+
To Garya По второму, а не по первому. Может конечно чего недонастроил, но пробовал всяко: из ASP когда открываешь процедуру, в которой select ...... и все, то все нормально, а если в ней куда-то есть insert ...., то обломись. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.10.2001, 07:04 |
|
||
|
Эффективнось запуска SP из ADO
|
|||
|---|---|---|---|
|
#18+
А в чем этот обломись заключается? Какое выводится сообщение об ошибке? Не "облом-с!" же? Наугад можно предположить, что проблемы могли возникнуть с правами доступа. Проблемы действительно могли возникнуть, если в хранимой процедуре используется динамический SQL. Часть запроса, которая сформировалась динамически, запускается в отдельном контенте и не с правами владельца хранимой процедуры, а с правами пользователя, который может не иметь достаточных прав для доступа к соответствующим таблицам напрямую. Больше с ходу ничего в голову не приходит. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.10.2001, 10:07 |
|
||
|
Эффективнось запуска SP из ADO
|
|||
|---|---|---|---|
|
#18+
Товарищи! Используйте всегда вариант 2. Он быстрее (а не как вы подумали) и надёжнее. Я встречался с такой ошибкой: в VB коннекшн перестаёт работать, пока не уничтожить последний объект ADODB.Command... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.10.2001, 11:53 |
|
||
|
Эффективнось запуска SP из ADO
|
|||
|---|---|---|---|
|
#18+
Всем спасибо за ответы! Я тоже думаю, что никакой разницы нет. Просто у нас на работе спор возник. Мы взяли на работу нового программиста, а он утверждает, что второй вариант вызывает перекомпиляцию процедуры при вызове. Принародно убеждать его я не стал, - на испытательном сроке человек. Но сам на всякий случай засомневался. Еще раз спасибо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.10.2001, 23:25 |
|
||
|
Эффективнось запуска SP из ADO
|
|||
|---|---|---|---|
|
#18+
Давно не брал я в руки шашки... Помнится, что вариант с Cmd.CommandType = adCmdStoredProc приводит к дополнительному запросу к серверу от ADO с целью получить метаданные - всякие там параметры процедурные... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.10.2001, 04:02 |
|
||
|
Эффективнось запуска SP из ADO
|
|||
|---|---|---|---|
|
#18+
2 AnatolyS Да, давненько Вы шашку не брали... Коллекеция параметров заполняется методоим .Refresh. Если тип команды - текст, то можно аказать/отказаться от его размещения в процедурном кэше свойством .Prepared. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.10.2001, 08:10 |
|
||
|
Эффективнось запуска SP из ADO
|
|||
|---|---|---|---|
|
#18+
Никогда!! не пользуйтесь методом 2. Только #1. Второй вариант вызывает перекомпиляцию пакета " exec my_cool_sp". Вы ведь спокойно могли написать "begin tran if ... begin ... end commit tran" или чего еще. Цитата из BOL "The prepared statement adds a small precompiled execution plan that calls the stored procedure execution plan, rather than executing the stored procedure execution plan directly." Во-вторых второй! а не первый вариант приводит к рефрешу параметров только на внутреннем уровне SQL Server. Как часть компиляции пакета. В-третьих производится двойное приведение типов: сначала на клиенте в строку, затем при разборе пакета обратно в тип параметров. В-четвертых вы теряете возможность получать out-параметры кроме как в рекордсете. Но рекордсет гораздо более ресурсоемкий объект, чем параметр (см. документацию к OLEDB). Ну и, наконец, не дай бог, пропустить кавычку или апостроф или столкнуться с разными LCID при составлении скрипта вызова SP. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.10.2001, 12:45 |
|
||
|
Эффективнось запуска SP из ADO
|
|||
|---|---|---|---|
|
#18+
Уважаемый George! Позволю с Вмаи не согласиться. П. 1. Действительно, #2 вызывает перекомпиляцию пакета " exec my_cool_sp". Однако время перекомпиляции столь мало, что его нельзя измерить. Несколько лет назад мы проводили тесты (я доказывал своему начальнику, что выриант #1 быстрее ), и быстрее оказался #2... П. 2. Под рефрешем параметров подразумевается запрос клиентом параметров процедуры у сервера. Первый вариант может приводить к рефрешу параметров при использовании метода рефреш. Второй вариант не может приводить к рефрешу параметров, т.к. их нет. "приводит к рефрешу параметров только на внутреннем уровне SQL Server" - это не рефреш, это компиляция стейтмента. П. 3. Это всё та-же компиляция стейтмента!!! Очень быстрая. П. 4. "рекордсет гораздо более ресурсоемкий объект" - это зависит от стиля написания и используемого окружения. Использовать нужно не RS("MyField"), а метод GetRows. При этом: П. 4а. ASP - рекордсет быстрее в десятки раз. Не забывайте, что использование Cmd.Parameters(...) - это обращение к ОЛЕ, поиск метода по имени(!!!), маршаллинг и т.д. - сотни тысяч команд процессора. Кроме того, для работы с #1 придётся вызывать десятки методов через ОЛЕ, а в #2 - только 3: set rs = conn.Execute(...) vArray = rs.GetRows() rs.Close И всё! Серверные ресурсы освобождены - можно работать с данными - причём быстро. П. 4б. Компилируемый язык - рекордсет медленнее при малом к-ве полей, и такой-же - при большом. П. 5. Главное преимущество #2 - меньше потенциальных ошибок, в частности потому, что всю работу с АДО можно вынести в отдельный модуль с 3-мя функциями. Простой пример - разработчикам пришла мысль, что хорошо-бы при сообщении о дедлоке повторять запрос. При методе 1 - переписывать приложение. При методе 2 - переписать одну функцию. Могу Вас уверить, что на своём и чужом опыте многократно убеждался использование первого метода ведёт к замедлению работы и уменьшению стабильности системы. С уважением, Алексей. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.10.2001, 08:30 |
|
||
|
Эффективнось запуска SP из ADO
|
|||
|---|---|---|---|
|
#18+
Не понимаю зачем копья ломать, когда можно в Trace посмотреть что делается. На самом деле в обоих случаях выполняется строчка "exec my_cool_sp". И именно эта строчка и будет компилироваться. С какой стати будет перекомпилироваться вся процедура? Во втором случае добавиться еще select для возвращаемых параметров и кода возврата. Предварительное чтение метаданных тоже будет, но только один раз - при следующем вызове процедуры их уже незачем читать. К тому же занимает это мгновение. 2 alexeyvg Не забывайте, что использование Cmd.Parameters(...) - это обращение к ОЛЕ, поиск метода по имени(!!!), маршаллинг и т.д. - сотни тысяч команд процессора. Бедный процессор, аж жалко стало. Ну посчитайте за сколько 100MHz процессор выполнит сто тысяч команд. А если еще учесть что он некоторые команды выполняет параллельно, по 2 за такт... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.10.2001, 09:53 |
|
||
|
Эффективнось запуска SP из ADO
|
|||
|---|---|---|---|
|
#18+
2SergSuper >Бедный процессор... Между прочим, это замедление существенно, оно заметно "на глаз". Сейчас не принято оптимизировать программы, а зря. Время выполнения плохо написанной АСП-страницы может дойти и до десятых долей секунды. Даже при небольшой нагрузке такое приложение загаживает целиком весь сервер. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.10.2001, 13:08 |
|
||
|
Эффективнось запуска SP из ADO
|
|||
|---|---|---|---|
|
#18+
> П. 3. Это всё та-же компиляция стейтмента!!! Очень быстрая. Конечно, компиляция стейтмента. Тут все есть компиляция стейтмента. Тут речь не о скорости выполнения пакета, т.к. ее действительно "нельзя измерить".А об уменьшении трудозатрат. Приходится больше программировать клиентскую часть. > Использовать нужно не RS("MyField"), а метод GetRows. Это кому как нравится. Метод GetRows вообще имеет массу недостатков. Копирование рекордсета в массив - на любителя. > Главное преимущество #2 - меньше потенциальных ошибок, в частности потому, что всю работу с АДО можно вынести в отдельный модуль с 3-мя функциями. Да - 3 функции это круто. Интересно, а зачем тогда в ADO их гораздо больше? Ведь достаточно только Connection.Execute(), а? Потенциальных ошибок не меньше - гораздо больше. И именно с приведениями типов при разных LCID клиента и сервера. >Между прочим, это замедление существенно, оно заметно "на глаз". Сейчас не принято оптимизировать программы, а зря. Время выполнения плохо написанной АСП-страницы может дойти и до десятых долей секунды. Если замедление вызывает создание пераметров, то АСП не просто полохо, а очень плохо написан. Например, если специально плохо написан. > Не забывайте, что использование Cmd.Parameters(...) - это обращение к ОЛЕ, поиск метода по имени(!!!), маршаллинг и т.д. - сотни тысяч команд процессора. Маршаллинг и IDispatch используется в любом случае, если работа идет из ASP. Если же работа идет из C++, то это как напишешь. Однако вызов SP методами объекта Command приводит к прямому RPC вызову нужной процедуры. Тогда как вызов SP методами объекта Recordset вызывает процедуру прекомпиляции пакета. Вообще, у Microsoft сказано: Don't return a rowset unless you must. ADO constructs a Recordset object whenever the query being executed returns rows. Recordset objects are expensive to construct, so avoid them whenever possible. After it's built, the Recordset provides powerful features, and if you find them useful, you can use a Recordset to pass data back from SQL Server. Keep in mind that it's possible to execute queries that return results but no rows. For example, you can return integer values by using the Return Status parameter. Also, you can return up to 1000 Output parameters (from SQL Server) instead of a rowset, which would require construction of a Recordset. Я думаю, что дискуссия безсмысленна. Каждый останется при своем мнении. Раньше я видел, написано было в BOL, что вызов хранимки методом Command является наиболее эффективным, но сейчас найти этой строчки не могу. Однако нигде в литературе вы не найдете строки, подтверждающей эффективность пункта 2. Везде при вызове SP используется Command de-facto. Иногда Connection (если out-параметров нет). Я какое-то время назад исследовал проблему вызова SP из ASP страниц. Сидел и с профайлером и груду лит-ры перечитал. Даже перехватывал RPC пакеты. Нашел груду неописанного MS поведения (например, для MS SQL 7.0 невозможно использовать Default-значения для out параметров). На мой взгляд, методы объекта Recordset нужно вообще использовать как можно реже. А рекомендаций по использованию разных ADO объектов в MSDN предостаточно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.10.2001, 09:17 |
|
||
|
Эффективнось запуска SP из ADO
|
|||
|---|---|---|---|
|
#18+
>В-четвертых вы теряете возможность получать out-параметры кроме как в рекордсете. Но рекордсет гораздо более ресурсоемкий объект, чем параметр (см. документацию к OLEDB). Вовсе мы ничего не теряем. Cmd.CommandText = "exec MyProc ?, ? ? output" Далее при создании коллекции параметров (это необходимо сделать самому) при создании третьего параметра необходимо указать direction=InputOutput И все! У меня работает. Кстати, при создании на клиенте "врукопашную" параметров (без метода Refresh) по первому методу имена параметрам необходимо давать в точности такие, как они даны в описании хранимой процедуры - вместе с символом @. По второму варианту имена параметров могут быть произвольные. И еще. Согласен с SergSuper. То, что приходит на сервер что по первому, что по второму варианту, отличается мало. Время компиляции одной строчки из трех слов - это не та тема, которую имеет смысл обсуждать. Лично я использую вариант 1 просто потому, что это удобнее (чуть меньше писанины), но только в тех случаях, когда речь не идет об sql_variant. Когда необходимо использовать sql_variant, альтернативы второму способу нет (см. выше). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.10.2001, 13:46 |
|
||
|
Эффективнось запуска SP из ADO
|
|||
|---|---|---|---|
|
#18+
>В-четвертых вы теряете возможность получать out-параметры кроме как в рекордсете. Но рекордсет гораздо более ресурсоемкий объект, чем параметр (см. документацию к OLEDB). Вовсе мы ничего не теряем. Cmd.CommandText = "exec MyProc ?, ? ? output" Далее при создании коллекции параметров (это необходимо сделать самому) при создании третьего параметра необходимо указать direction=InputOutput И все! У меня работает. Кстати, при создании на клиенте "врукопашную" параметров (без метода Refresh) по первому методу имена параметрам необходимо давать в точности такие, как они даны в описании хранимой процедуры - вместе с символом @. По второму варианту имена параметров могут быть произвольные. И еще. Согласен с SergSuper. То, что приходит на сервер что по первому, что по второму варианту, отличается мало. Время компиляции одной строчки из трех слов - это не та тема, которую имеет смысл обсуждать. Лично я использую вариант 1 просто потому, что это удобнее (чуть меньше писанины), но только в тех случаях, когда речь не идет об sql_variant. Когда необходимо использовать sql_variant, альтернативы второму способу нет (см. выше). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.10.2001, 13:48 |
|
||
|
Эффективнось запуска SP из ADO
|
|||
|---|---|---|---|
|
#18+
>В-четвертых вы теряете возможность получать out-параметры кроме как в рекордсете. Но рекордсет гораздо более ресурсоемкий объект, чем параметр (см. документацию к OLEDB). Вовсе мы ничего не теряем. Cmd.CommandText = "exec MyProc ?, ? ? output" Далее при создании коллекции параметров (это необходимо сделать самому) при создании третьего параметра необходимо указать direction=InputOutput И все! У меня работает. Кстати, при создании на клиенте "врукопашную" параметров (без метода Refresh) по первому методу имена параметрам необходимо давать в точности такие, как они даны в описании хранимой процедуры - вместе с символом @. По второму варианту имена параметров могут быть произвольные. И еще. Согласен с SergSuper. То, что приходит на сервер что по первому, что по второму варианту, отличается мало. Время компиляции одной строчки из трех слов - это не та тема, которую имеет смысл обсуждать. Лично я использую вариант 1 просто потому, что это удобнее (чуть меньше писанины), но только в тех случаях, когда речь не идет об sql_variant. Когда необходимо использовать sql_variant, альтернативы второму способу нет (см. выше). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.10.2001, 13:49 |
|
||
|
|

start [/forum/topic.php?fid=46&gotonew=1&tid=1825182]: |
0ms |
get settings: |
8ms |
get forum list: |
17ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
37ms |
get topic data: |
10ms |
get first new msg: |
5ms |
get forum data: |
2ms |
get page messages: |
68ms |
get tp. blocked users: |
1ms |
| others: | 253ms |
| total: | 407ms |

| 0 / 0 |
