|
Есть ли разница в исполнении запроса ?
|
|||
---|---|---|---|
#18+
Привет Всем! Волнует следующий вопрос Есть ли разница, с точки зрения производительности, в исполнении хранимой процедуры, когда запрос написан в явном виде и когда текст запроса заноситься в переменную и вызывается с помощью execute(@myvar) ? ... |
|||
:
Нравится:
Не нравится:
|
|||
12.03.2001, 10:07 |
|
Есть ли разница в исполнении запроса ?
|
|||
---|---|---|---|
#18+
Если я не ошибаюсь, то в случае явного запроса сервер после выполнения хранит его в откомпилированном виде и собирает на него статистику, в результате чего у сервера есть возожность оптимизировать его выполнение в дальнейшем. В случае с execute такой возможности у него нет, поскольку он не знает этого запроса, и к тому же ему каждый раз приходится его компилировать. Я использую execute только в том случае, если без этого не могу обойтись. ... |
|||
:
Нравится:
Не нравится:
|
|||
12.03.2001, 11:05 |
|
Есть ли разница в исполнении запроса ?
|
|||
---|---|---|---|
#18+
На мой взгдя есть. Дело в том, что при явном указании запроса, при сохранении SP, она компилируется, т.е. строится ее план. При занесении же запроса в переменную с последующим использованием Execute план этой части заранее построить в общем случае нельзя и поэтому, я так понимаю, он и не пытается строить этот план. Так что при выполнении будет уходить время на построение плана выполнения execute. ... |
|||
:
Нравится:
Не нравится:
|
|||
12.03.2001, 11:07 |
|
Есть ли разница в исполнении запроса ?
|
|||
---|---|---|---|
#18+
А если имеется 20-30 типовых запросов, имеющих как общие условия в частях SELECT, WHERE и GROUP так и разные, которые зависят от входных параметров (поэтому и используется переменная для формирования запроса), то что тогда писать отдельную процедуру на каждый запрос ? Но чем больше процедур, тем сложнее за ними следить, особенно если придется вносить изменения в общую часть всех запросов. Или здесь нет точного рецепта и придется искать компромисс между "удобно для сервера" и "удобно для админа" ? ... |
|||
:
Нравится:
Не нравится:
|
|||
12.03.2001, 11:34 |
|
Есть ли разница в исполнении запроса ?
|
|||
---|---|---|---|
#18+
... |
|||
:
Нравится:
Не нравится:
|
|||
12.03.2001, 12:04 |
|
Есть ли разница в исполнении запроса ?
|
|||
---|---|---|---|
#18+
20-30 умножаем на 10-15 таблиц получаем Ну а в общем - понятно: все для юзера ... |
|||
:
Нравится:
Не нравится:
|
|||
12.03.2001, 12:12 |
|
Есть ли разница в исполнении запроса ?
|
|||
---|---|---|---|
#18+
Dmitry и Genady чуть ли не слово в слово высказали мысль(на мой взгляд неверную), что "при занесении же запроса в переменную с последующим использованием Execute план этой части заранее построить в общем случае нельзя". Интересно почему? Запрос в Execute всё равно сначала компилируется и значит строиться план. Не знаю как в SQL2000, но в 6.5 я в процедуре специально использовал Execute для того чтобы запрос мог использовать индексы во временной таблице. Дело в том что при компиляции процедуры еще неизвестно что индекс будет и он не используется. Если же писать через Exec, то компиляция произойдет непосредственно перед выполнением и индекс подхватиться. ... |
|||
:
Нравится:
Не нравится:
|
|||
12.03.2001, 12:33 |
|
Есть ли разница в исполнении запроса ?
|
|||
---|---|---|---|
#18+
>20-30 умножаем на 10-15 таблиц получаем Ну здесь Вам прийдется попридумывать А вобще то, я полагал, что запросы у Вас предназначены для отчетов, а в таких запросах как правило приходиться соединять несколько таблиц, вот поэтому и полагал, что этих запросов всего 20-30 ... |
|||
:
Нравится:
Не нравится:
|
|||
12.03.2001, 12:33 |
|
Есть ли разница в исполнении запроса ?
|
|||
---|---|---|---|
#18+
2 SergSuper Безусловно план выполнения запроса в любом случае строится, но в случае с execute он строится заново, а в случае с явным запросом, он просто храниться на сервере и при запросе выполняется. ... |
|||
:
Нравится:
Не нравится:
|
|||
12.03.2001, 12:48 |
|
Есть ли разница в исполнении запроса ?
|
|||
---|---|---|---|
#18+
Я бы на месте Glory просто промерял бы быстродействие в обоих случаях, тем более, что у него большая база и расхождения должны быть явно видны ... |
|||
:
Нравится:
Не нравится:
|
|||
12.03.2001, 12:51 |
|
Есть ли разница в исполнении запроса ?
|
|||
---|---|---|---|
#18+
Да в том-то и дело, что при общем времени исполнения запроса 20-25 минут, я не вижу больших расхождений во времени(не более 5 минут) при запуске из QA процедуры, которая использует execute и запуске явно составленного запроса из того же QA. Может быть, конечно, дело в том, что у тестируемых таблиц уже имеется статистика, уже построенная по рекомендациям ITW. ... |
|||
:
Нравится:
Не нравится:
|
|||
12.03.2001, 12:59 |
|
Есть ли разница в исполнении запроса ?
|
|||
---|---|---|---|
#18+
Может быть выигрыш будет при одновременном запуске запроса с нескольких коннектов. Тогда, как я понимаю, план выполнения для одинаковых запросов может быть одновременно использован разными коннектами(пользователями), если используется явное написание запроса а не execute. Так ли это ? ... |
|||
:
Нравится:
Не нравится:
|
|||
12.03.2001, 13:14 |
|
Есть ли разница в исполнении запроса ?
|
|||
---|---|---|---|
#18+
Если я правильно понял из BOL, то сервер в любом случае хранит план запроса, просто план процедуры хранится постоянно, а динамического запроса до тех пор пока подобные запросы поступают. SQL Server 7.0 execution plans have two main components: 1. Query plan 1. Execution context Собственно Query plan это и есть план запроса, а Execution context это план выполнения, зависящий от конкретного подключения, т.е. select * from MyTable where PriKey = ? - Query plan select * from MyTable where PriKey = 45 - Execution plan построенный на основе Query plan. В случае явного запроса Query plan хранится обязательно, а хранится ли он при динамическом я не знаю, пойду покопаюсь в BOL ... |
|||
:
Нравится:
Не нравится:
|
|||
12.03.2001, 13:34 |
|
Есть ли разница в исполнении запроса ?
|
|||
---|---|---|---|
#18+
Если кретично время а кол-во процедур 450 (30 запросов * 15 таблиц), то можно написать одну служебную процедуру, которая создает в БД эти 450 прикладных процедур. ... |
|||
:
Нравится:
Не нравится:
|
|||
12.03.2001, 14:05 |
|
Есть ли разница в исполнении запроса ?
|
|||
---|---|---|---|
#18+
> А если имеется 20-30 типовых запросов, имеющих как общие условия в частях SELECT, WHERE > и GROUP так и разные, которые зависят от входных параметров (поэтому и используется > переменная для формирования запроса), то что тогда писать отдельную процедуру на каждый > запрос ? Если вы используете технологи ADO, то в ней специально для решения данной задачи имеются средства - параметризованные prepared-запросы. Повторяю, через ODBC эта фича недоступна - только через ADO. В свойствах ADO-компонента присваивается prepared=true, задается текст запроса, в который вместо значений параметров (переменной части запроса) подставляются либо имена параметров, предваряемые двоеточием (в Delphi), либо знаки вопроса (в VBA). Дополнительно создается коллекция ADO-параметров, которая цепляется к данному ADO-компоненту, в которых и указываются значения параметров. При выполнении такого запроса он компилируется на сервере только первый раз. При компиляции SQL-сервер "знает" о переменных и постоянных частях запроса, то есть план запроса составляется так, как при компиляции хранимых процедур с параметрами. Данный план некоторое время хранится в кэше даже если пославший запрос юзер разорвал соединение. Если от этого же или даже от другого юзера придет аналогичный запрос с другими значениями параметров, то повторная компиляция не производится - подставляются новые значения параметров в ранее сгенеренный план, и запрос выполняется. В чем отличие SP от параметризованных запросов? 1. Если долгое время не посылать повторно такой запрос на сервер, то план запроса будет вытеснен из кэша и утерян. Это вызовет повторную компиляцию запроса при его повторном получении сервером. 2. Хранимые процедуры возвращают необновляемый набор данных. Параметризованный запрос может возвращать обновляемый набор данных. ... |
|||
:
Нравится:
Не нравится:
|
|||
12.03.2001, 20:56 |
|
Есть ли разница в исполнении запроса ?
|
|||
---|---|---|---|
#18+
Если время выполнения запроса = 20-25 МИНУТ, то я не думаю, что будет какая-то ощутимая разница. Как уже много раз говорилось выше, существует два этапа - составление плана и собственно выполнение. Разница между динамическим запросом и SP - в том, что в SP план уже готов и его не надо вновь формировать, а взапросе - надо (если его нет в кэше). Так вот я с трудом могу представить, чтобы время составления запроса было сравнимо с 20-25 минутами, или даже на порядок меньше. Так что разница за счет времени составления запроса конечно будет, но она будет пренебрижимо мала... ... |
|||
:
Нравится:
Не нравится:
|
|||
13.03.2001, 14:09 |
|
Есть ли разница в исполнении запроса ?
|
|||
---|---|---|---|
#18+
2 Garya: На чем основано утверждение, что хранимые процедуры возвращают необновляемый набор записей? ... |
|||
:
Нравится:
Не нравится:
|
|||
13.03.2001, 14:31 |
|
Есть ли разница в исполнении запроса ?
|
|||
---|---|---|---|
#18+
2Dmitry По-моему это правильно. Для одного коннекта уж точно, а что-будет в случае многих коннектов ? 2Garya Не знаю,конечно,как в ADO и Delphi,но в VFP 7.0(да и 6.0, кажется)есть функция SQLPREPARE(), которая прекрасно работает и при использовании ODBC. ... |
|||
:
Нравится:
Не нравится:
|
|||
13.03.2001, 14:58 |
|
Есть ли разница в исполнении запроса ?
|
|||
---|---|---|---|
#18+
2 Glory В случае множества коннектов сервер будет использовать план запроса из кешаб этот план будет построен после первого выполнения этого запроса. Что касается процедур, то в BOL написано, что кроме того, что сервер хранит план запроса, он еще и оптимизирует выполнение процедуры с каждым ее запуском, в случае с динамичесим запросом вероятно он этого делать не может. Насколько хороша эта оптимизация не знаю. Я бы все же сделал процедуры по обеим принципам и попробовал бы погонять их. Несколько запусков я полагаю мало. ... |
|||
:
Нравится:
Не нравится:
|
|||
13.03.2001, 15:12 |
|
Есть ли разница в исполнении запроса ?
|
|||
---|---|---|---|
#18+
Следовательно, хотя бы теоритически выигрыш при множественных коннектах все-таки будет ? ... |
|||
:
Нравится:
Не нравится:
|
|||
13.03.2001, 15:25 |
|
Есть ли разница в исполнении запроса ?
|
|||
---|---|---|---|
#18+
Выигрыш в каком случае? План запроса в любом случае используется повторно. А вот насчет оптимизации, как я уже говорил не знаю, совет - измерьте. ... |
|||
:
Нравится:
Не нравится:
|
|||
13.03.2001, 15:38 |
|
Есть ли разница в исполнении запроса ?
|
|||
---|---|---|---|
#18+
2 All: В моей предыдущей реплике фразу "время составления запроса" следует читать как "время составления плана" 2 Genady: что значит "оптимизирует выполнение процедуры с каждым ее запуском"? С каждым разом все лучше и лучше что ли? А можно оригинал (из BOL)? Я так понимаю что план строится как раз для оптимизации и не перестраивается до применения sp_Recompile. Либо же он перестраивается каждый раз, если указано with recompile и тогда не отличается от динамического запроса. (при этом действительно возможно составление более оптимального плана на текущий момент при условии обновления статистики). 2 Glory: даже при вытеснении плана из кэша, при множественных коннектах время на составление плана несравнимо с 20-25 мин И если уж коннекты ОЧЕНЬ множественные (настолько что формироваине плана даст сильную нагрузку и будет сильно сказываться на поризводительности), то остается только пожалеть сервер, которому придется кроме того справляться с такой интенсивностью ТАКИХ запросов. ... |
|||
:
Нравится:
Не нравится:
|
|||
13.03.2001, 18:34 |
|
Есть ли разница в исполнении запроса ?
|
|||
---|---|---|---|
#18+
... |
|||
:
Нравится:
Не нравится:
|
|||
13.03.2001, 18:51 |
|
Есть ли разница в исполнении запроса ?
|
|||
---|---|---|---|
#18+
2Dmitry: Согласен. Если запрос вызывается 2-3 раза и выполняется 20-30 минут при каждом вызове, время составления плана запроса мало имеет значения. Однако, на практике могут встречаться задачи выполнения в цикле одного и того же параметризованного запроса (с малым временем выполнения) в новым значением параметров на каждом шаге цикла. Если число циклов 1000 и более, а время выполнения запроса мало, то время его компиляции и составления плана оказывается весьма существенным. 2Павел: А тебе известен способ вставки записей в возвращаемый хранимой процедурой набор данных? Что-нибудь вроде Isert into exec MyProc... или Insert into MyProc...? 2Glory: Насчет SQLPrepare. Припоминаю - что-то такое в ODBC действительно было. Приношу извинения за недостоверную информацию. Я мало работал через ODBC, все больше через ADO. ... |
|||
:
Нравится:
Не нравится:
|
|||
13.03.2001, 19:13 |
|
Есть ли разница в исполнении запроса ?
|
|||
---|---|---|---|
#18+
Кстати, я читал в какой-то статье (по-моему на сайте MS) о том, как работает оптимизатор SQL-сервера. Он учитывает такую вешь, как стоимость оптимизации, и производит ее поэтапно. Сначала делается черновая грубая оценка времени выполнения запроса. Если оно получается малым, то дальнейшая оптимизация не выполняется, поскольку затраты времени на оптимизацию могут оказаться выше затрат времени на выполнение запроса с грубо построенным планов выполнения. Если же предварительные результаты оценки показывают, что время выполнения запроса должно быть достаточно большим, производится его более тщательная оптимизация для уменьшения этого времени. IMHO, довольно грамотный поход. ... |
|||
:
Нравится:
Не нравится:
|
|||
13.03.2001, 19:21 |
|
Есть ли разница в исполнении запроса ?
|
|||
---|---|---|---|
#18+
Насчет "мелких" запросов - само собой. Я говорил только о "крупных". Насчет "поэтапной" оптимизации - мне казалось что это справедливо, но только для динамических запросов. Для SP - можно один раз напрячься по полной программе, зато потом наслаждаться Можно ссылочку на MS? Вообще, при оптимизации можно рассматривать ОЧЕНЬ большое число вариантов. Для уменьшения расходов на нее, количество рассматриваемых вариантов осознанно ограничивается. При этом в принципе допускается, что наиболее оптимальный вариант рассмотрен не будет. Число рассматриваемых вариантов будет ограничено независимо от того "большой" запрос или "маленький". Не знаю, как у MSSQL, но это то, что я читал по БД вообще. ... |
|||
:
Нравится:
Не нравится:
|
|||
14.03.2001, 01:03 |
|
Есть ли разница в исполнении запроса ?
|
|||
---|---|---|---|
#18+
2 Garya: >2Павел: А тебе известен способ вставки записей в возвращаемый хранимой процедурой набор данных? >Что-нибудь вроде Isert into exec MyProc... или Insert into MyProc...? Конечно не известен. Нет такого сособа. А вот интерестности: При указании в форме проекта А2K в качестве источника записей таблицы, запроса, представления или хранимой процедуры и при указании уникальной таблицы в профайлере отчетливо видно, что изменение данных происходит не через источник записей, а через уникальную таблицу. Так что в этом случае процедура также как-бы обновляема, как и запрос и представление. Понятно, конечно, что это частный случай. Вот только не разобрался, Ассеss так себя ведет, или ADO. ... |
|||
:
Нравится:
Не нравится:
|
|||
14.03.2001, 07:47 |
|
Есть ли разница в исполнении запроса ?
|
|||
---|---|---|---|
#18+
2 Garya: >2. Хранимые процедуры возвращают необновляемый набор данных. >Параметризованный запрос может возвращать обновляемый набор данных. А тебе известен способ вставки записей в возвращаемый запросом набор данных? Что-нибудь вроде Isert into <Запрос>? ... |
|||
:
Нравится:
Не нравится:
|
|||
14.03.2001, 08:38 |
|
Есть ли разница в исполнении запроса ?
|
|||
---|---|---|---|
#18+
2 Dmitry Вот блин, щас перерыл всю BOL и не нашел фразы которую якобы читал вчера (по оптимизации выполнения процедур) из чего следует сделать вывод, что я что то напутал, сорри 8-() ... |
|||
:
Нравится:
Не нравится:
|
|||
14.03.2001, 10:32 |
|
Есть ли разница в исполнении запроса ?
|
|||
---|---|---|---|
#18+
2Павел. В A2K действительно у формы имеется свойство "уникальная таблица", которая позволяет "обмануть" необновляемость набора данных. На самом деле это просто прием, который используется исполняющей системой на самом клиенте - вместо работы с источником данных, который вернул запрос, A2K производит операции вставки/изменения/удаления с уникальной таблицей, которая специально указана как базовый источник данных. В общем случае уникальная таблица может вообще никакого отношения не иметь к данным, возвращенным в запросе ( это я к тому, что следует различать действительно обновляемый набор данных и всякого рода обманки, выполняемые на клиенте). Если параметризованный запрос выполнить через ADO, при условии что аналогичный НЕпараметризованный запрос также возвращает обновляемый набор данных, на клиенте появляется Bookmarkable recordset (терминология OLEDB), который и является условием обновляемости набора данных. Если, к примеру, в Delphi такой набор данных просвечен через DBGrid, то ты можешь непосредственно в нем модифицировать данные, не прибегая ко всякого рода обманкам. Модификация приводит к обращению на SQL-сервер напрямую к нужной записи через механизм Bookmark (меток записи). 2 Dmitry. Лови ссылочку на статьи (там много интересных, включая ту, о которой я говорил) http://www.microsoft.com/rus/sql/rusdocs.html. ... |
|||
:
Нравится:
Не нравится:
|
|||
14.03.2001, 21:52 |
|
Есть ли разница в исполнении запроса ?
|
|||
---|---|---|---|
#18+
2 Garya: >Если параметризованный запрос выполнить через ADO, при условии что аналогичный НЕпараметризованный запрос также возвращает обновляемый набор данных, на клиенте появляется Bookmarkable recordset (терминология OLEDB), который и является условием обновляемости набора данных Это особенности реализации конкретного механизма доступа к данным. В любом случае все клиентские действия должны быть преобразованs в адекватные команды TSQL. Как уже отмечалось, не существует способа выполнить "Что-нибудь вроде Insert into exec MyProc... или Insert into MyProc" или "Что-нибудь вроде Insert into <Запрос>". Операции изменения данных доступны напрямую только для таблиц и представлений. Так чем, в таком случае, обновляемость набора записей, возвращенных процедурой, отличается от обновляемости набора записей, возвращенного запросом? ... |
|||
:
Нравится:
Не нравится:
|
|||
15.03.2001, 07:03 |
|
Есть ли разница в исполнении запроса ?
|
|||
---|---|---|---|
#18+
2 Павел. Возможно, ты в чем-то прав, и я не совсем корректно попросил привести текст на T-SQL, доказывающий обновляемость набора данных. Однако, в OLEDB такое понятие существует. Известно, что хранимые процедуры возвращают необновляемый набор данных. Если открыть в ADO набор данных, возвращенный SP, то он В СВОЙСТВАХ ADO.Recordset покажет, что набор необновляемый. Ежели выдать команду select ..... чего-нибудь откуды-нибудь, то можно получить набор данных как обновляемый, так и не обновляемый. Вариант указания уникальной таблицы относится к конкретному инструментарию (Access-2000), и более нигде не катит. В Delphi также есть компоненты, выполняющие аналогичные обманные телодвижения. Кстати, в отличие от A2K, в них можно даже сделать так, что вставка будет идти в одну таблицу, модификация будет выполняться над второй, а удаление - в третей. Трудно себе представить, кому такое может понадобиться, но все это сказано лишь с целью подчеркнуть ориентированность определенных приемов на определенный инструментарий. Я же отвечал вообще - без привязки к конкретному инструментарию, а только к механизмам ADO, которые ведут себя схоже в любом инструментарии. Когда ты в EM открываешь таблицу и модифицируешь в ней строку, то на сервер приходит команда не Update... (которую в аналогичной ситуации формирует A2K), а "exec sp_executesql N'UPDATE......". И еще несколько строк. Подобные строки может формировать ODBC-драйвер, само приложение, а может формировать OLEDB-провайдер, который в общем случае от используемого на клиенте инструментария независим. Вот я о чем. ... |
|||
:
Нравится:
Не нравится:
|
|||
15.03.2001, 21:26 |
|
Есть ли разница в исполнении запроса ?
|
|||
---|---|---|---|
#18+
2 Garya: Use pubs go Create Procedure sp_authors As Set Nocount On Select * From Authors Return go Предполагается, что проект adp A2K уже имеет соединение с базой pubs Dim cmd As New Command, rst As New Recordset rst.ActiveConnection = CurrentProject.Connection rst.CursorLocation = adUseServer rst.CursorType = adOpenStatic rst.Source = "Select * From dbo.authors" rst.Open Debug.Print rst.Properties("Updatability").Name & ", " & rst.Properties("Updatability").Value Debug.Print rst.Properties("Bookmarkable").Name & ", " & rst.Properties("Bookmarkable").Value Debug.Print rst.Properties("Unique Table").Name & ", " & rst.Properties("Unique Table").Value rst.Close Set rst = Nothing cmd.ActiveConnection = CurrentProject.Connection cmd.CommandText = "dbo.sp_authors" cmd.CommandType = adCmdStoredProc cmd.Prepared = False Set rst = cmd.Execute Debug.Print rst.Properties("Updatability").Name & ", " & rst.Properties("Updatability").Value Debug.Print rst.Properties("Bookmarkable").Name & ", " & rst.Properties("Bookmarkable").Value Debug.Print rst.Properties("Unique Table").Name & ", " & rst.Properties("Unique Table").Value rst.Close Set rst = Nothing Set cmd = Nothing В Immediate: Updatability, 7 Bookmarkable, True Unique Table, Updatability, 7 Bookmarkable, True Unique Table, Какие мысли? ... |
|||
:
Нравится:
Не нравится:
|
|||
16.03.2001, 07:30 |
|
Есть ли разница в исполнении запроса ?
|
|||
---|---|---|---|
#18+
Я пересказал то, что вычитал (насколько помню, у Дженнингса). Видимо одного свойства Bookmarkable=True недостаточно для того, чтобы получить обновляемый набор данных (однако, если Bookmarkable=false, то набор данных однозначно необновляемый). Видимо, я не совсем правиИнтересно, а что выдаст Debug.Print rst.Supports(adAddNew)? Полагаю, что в первом случае True, а во втором False. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.03.2001, 18:02 |
|
Есть ли разница в исполнении запроса ?
|
|||
---|---|---|---|
#18+
Отвлекли ... случайно нажал "отправить". Я хотел сказать, что видимо, не совсем правильно понимал Bookmarkable как исключительное требование обновляемости. Исходя из сказанного Павлом, я полагаю, что это возможность прицепиться к первичному ключу, однозначно идентифицирующего запись - то есть, одно из требований обновляемости набора данных. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.03.2001, 18:07 |
|
|
start [/forum/topic.php?all=1&fid=46&tid=1827176]: |
0ms |
get settings: |
9ms |
get forum list: |
13ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
28ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
58ms |
get tp. blocked users: |
2ms |
others: | 12ms |
total: | 140ms |
0 / 0 |