Re[18]: Кеширование и параметризация запросов
От: Merle Австрия http://rsdn.ru
Дата: 02.12.04 09:35
Оценка: 92 (6)
Здравствуйте, pkarklin, Вы писали:

P>Пожалйуста, подкрепите свои слова ссылками на BOL, MSDN, KB, наконец, собственный эксперимент.

Да запросто, просто ход предыдущей дискуссии никаких ссылок на авторитетные источники не предполагал...
На самом деле в BOL или MSDN я ссылок на подробное объяснение механизма кеширования не припомню, мои знания берутся в основном из личного опыта и общения непосредственно с разработчиками SQL сервера.
Если интересно могу попросить у них ссылки на открытые источники в которых это описано, но не обещаю, что это будет быстро.. Ну вернемся к экспериментам.
Во-первых, скешировался параметризованный план или нет, всегда можно посмотреть с помощю замечательной команды SET SHOWPLAN_TEXT ON, в плане всегда видно подставилась ли там константа (e. g. WHERE[tbl1].[a]=Convert(1)), или параметр (e. g. WHERE[tbl1].[a]=Convert([@1]))
Для более подробного исследования полезно взглянуть на системную табличку master..syscacheobjects, которая собственно и отражает, что же за планы хранятся в сервере. В общих словах, как примерно все устроено:
Допустим поступил запрос в сервер, запрос разбирается, парсится и подготавливается план запроса.
План может быть нескольких типов, но нас сейчас интересуют всего два: Ad-hoc queries — это, очевидно, план с константами, и parameterized queries, соответственно с параметрами.
Итак, у нас есть план запроса, это некоторая Read Only структура, к которой могут одновременно обращаться сколько угодно желающих. При этом планов реально два, один для последовательного исполнения, а другой для распараллеливания.
Но это далеко не все, каждому плану принадлежат так называемые контексты исполнения (execution context), которые и отвечают, что на самом деле реально исполняется, эти контексты исполнения так же кешируются и переиспользуются. Каждый реально исполняющийся запрос имеет свой собственный контекст исполнения, который содержит параметры, данные, ect... И еще один нюанс, не смотря на то, что контексты кешируются, одновременно использовать один контекст может только один запрос. Соответственно для каждого плана есть несколько контекстов (хотя может и не быть ни одного).
Таким образом, сначала ищется в кеше подходящий план, если нашелся, ищется подходящий контекст из имеющихся, далее либо находится и используется, либо готовится новый. Ну да это все лирика, теперь самое время для полевых испытаний:
Готовим тестовые данные и очищаем кеш:
drop table tbl1
create table tbl1(a int)

insert into tbl1(a)
select 1 union
select 2 union
select 3 union
select 4 union
select 5 union
select 6 union
select 7 union
select 8 union
select 9 union
select 10 

DBCC FREEPROCCACHE

Теперь выполняем запрос и смотрим что происходит в таблице кеша, где нас будут интересовать следующие поля:
cacheobjtype — что за объект кеширования(план или контекст), objtype — с константой или нет, usecounts — сколько раз использовался, sql — что собственно скешировалось.
select a from tbl1 where a=7
GO
select cacheobjtype, objtype, usecounts, sql from master..syscacheobjects

В результате видим:
Compiled Plan     | Adhoc        |1|    select a from tbl1 where a=7  
Executable Plan    | Prepared    |1|    (@1 tinyint)SELECT [a]=[a] FROM [tbl1] WHERE [a]=@1
Compiled Plan      | Prepared    |2|    (@1 tinyint)SELECT [a]=[a] FROM [tbl1] WHERE [a]=@1

У нас есть план с константой (Adhoc), который использовался один раз.
В первой колонке Compiled Plan означает собственно готовый план запроса, а Executeble Plan — означает контекст исполнения.
Во второй, Ad-hoc означает, что план с константой, Prepared, что сиквел этот план может параметризовать.
Циферка — количество использования данного плана/контекста.
Повторяем эксперимент, с другой константой:
select a from tbl1 where a=8
GO
select cacheobjtype, objtype, usecounts, sql from master..syscacheobjects

Картина та же самая, только еще один Ad-hoc запрос добавился
Compiled Plan     | Adhoc        |1|    select a from tbl1 where a=7  
Compiled Plan     | Adhoc        |1|    select a from tbl1 where a=8  
Executable Plan    | Prepared    |1|    (@1 tinyint)SELECT [a]=[a] FROM [tbl1] WHERE [a]=@1
Compiled Plan      | Prepared    |2|    (@1 tinyint)SELECT [a]=[a] FROM [tbl1] WHERE [a]=@1

Выполняем еще раз, с еще одной константой:
select a from tbl1 where a=9
GO
select cacheobjtype, objtype, usecounts, sql from master..syscacheobjects

Смотрим:
Compiled Plan     | Adhoc        |1|    select a from tbl1 where a=7  
Compiled Plan     | Adhoc        |1|    select a from tbl1 where a=8  
Executable Plan    | Prepared    |2|    (@1 tinyint)SELECT [a]=[a] FROM [tbl1] WHERE [a]=@1
Compiled Plan      | Prepared    |2|    (@1 tinyint)SELECT [a]=[a] FROM [tbl1] WHERE [a]=@1

Уупс, Adhoc с девяткой не появился, однако счетчик использования параметризованного контекста увеличился на еденичку, то есть реально был использован параметризованый контекст.
В дальнейшем, какие бы цифры не были подставлены, новых Adhoc'ов не появляется, а лишь увеличивается счетчик контекста, из чего можно сделать вывод, что используется параметризованный план.

Ясен хвост, что автоматически распознать что можно параметризовать, а что нельзя сиквел может далеко не всегда, поэтому очень приветствуется явное указание что именно мы хотим параметризовать.
И сделать это можно двумя способами, либо указывая вопросики и передавая параметры в должном порядке, либо используя процедуру sp_executesql, что и делают большинство клиентских библиотек.

P>Заранее благодарен, по жизни заблуждающийся pkarklin.

Всегда пожалуйста..
... [ RSDN@Home 1.1.4 revision 0 ]
Мы уже победили, просто это еще не так заметно...
Re[10]: Кеширование и параметризация запросов
От: Sinclair Россия https://github.com/evilguest/
Дата: 30.11.04 09:54
Оценка: :))
Здравствуйте, Softwarer, Вы писали:
S>Могу дать ссылку на обсуждение — сам, извини, не проверял, так что передаю слова этого человека, на которые никто не возразил.
S>P.S. Я тоже был здорово удивлен
Давай ссылку. Щас разберемся, кто там что у кого не поддерживает
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Кеширование и параметризация запросов
От: Softwarer http://softwarer.ru
Дата: 30.11.04 07:13
Оценка: 21 (1)
Здравствуйте, Дм.Григорьев, Вы писали:

ДГ>Других корректных точно не помню (наверное, потому что по сравнению с этим они не убедительны ) но по смутным воспоминаниям выигрыш в несколько раз получался.


Это существенно зависит от того, что за база, что за отчеты, и так далее.

Скажем, не так давно человек меня убеждал, что единственный путь добиться скорости — все делать на хранимых процедурах. В результате из его объяснений выяснилось, что MS SQL не поддерживает binding параметров в SQL-запросах, вот и вся причина — чтобы не парсить постоянно запрос, его приходится обертывать в хранимку.

02.12.04 12:56: Ветка выделена из темы Выбор СУБД или что происходит в нише
Автор: squiz
Дата: 28.11.04
— Merle
Re[14]: Кеширование и параметризация запросов
От: Softwarer http://softwarer.ru
Дата: 01.12.04 07:57
Оценка: 6 (1)
Здравствуйте, Merle, Вы писали:

M>Да он там по жизни заблуждается, да и вообще, sql.ru для здоровья читать — вредно, до обеда..


Ораклоиды там компетентные. Странно, если mssql-евцы — поголовно левые.
Re[12]: Кеширование и параметризация запросов
От: wildwind Россия  
Дата: 30.11.04 12:15
Оценка: +1
Здравствуйте, Softwarer, Вы писали:

S>Одно дело — "не появилось", а другое дело — "появившееся сделано плохо". Если первое — именно что вопрос времени (развития, итп), то второе — показывает некомпетентных специалистов либо наплевательский подход к результату, что скорее всего скажется и в следующих версиях.


Все верно, если мы говорим о поделках студентов или начинаниях увлеченных идеей энтузиастов. Но у лидеров отрасли (в частности и особенно у MS) ни того ни другого не наблюдается в принципе. Тут действуют другие силы. И Oracle, так же как и MS, подгоняемая конкуренцией и технологической "гонкой вооружений", вынуждена выпускать новые фичи в своих продуктах сырыми и глючными. А потом, когда продукт уже выпущен, пресс-релизы разосланы, и пальма первенства удержана, доделывать, вылизывать, и умасливать недовольных патчами и сервис-паками. Это не так страшно, как упустить момент и потерять бОльшую часть нового рынка. Ничего, что потеряли тысячу старых разработчиков, зато приобрели десять тысяч новых! Хитрые старые лисы, пишущие бестселлеры по управлению IT бизнесом, видно не зря едят свой хлеб.

Пардон, что-то на лирику потянуло.
Re[15]: Кеширование и параметризация запросов
От: Merle Австрия http://rsdn.ru
Дата: 01.12.04 16:21
Оценка: -1
Здравствуйте, Softwarer, Вы писали:

S>Ораклоиды там компетентные. Странно, если mssql-евцы — поголовно левые.

Не поголовно, но, IMHO, толковых там катастрофически мало... Ну не люблю я его (sql.ru)...
... [ RSDN@Home 1.1.4 rev 0 ]
Мы уже победили, просто это еще не так заметно...
Re[18]: Кеширование и параметризация запросов
От: Merle Австрия http://rsdn.ru
Дата: 01.12.04 16:21
Оценка: +1
Здравствуйте, Softwarer, Вы писали:

S>А насколько дорого это обходится в случае, когда разработчик не заблуждается?

Да практически ни на сколько. Задачи когда нужно держать отдельный план для какой-то константы встречаются крайне редко, и, как правило, решаются хинтами.

S> Смущает другое: в ситуации, когда в принципе предусмотрено вытеснение из кэша (то есть я не могу выделить под планы столько места, чтобы они никогда не вытеснялись) сервер может решить параметризировать те запросы, которые я настоятельно хотел бы оставить с константами.

Если запрос пользуется с константой, одной/двумя, то он так с этой константой в кеше и останется. А вот если запрос с константой, но при каждом новом запросе константа разная, то в какой-то момент сервер совершенно справедливо забъет на эти константы и начнет использовать параметры.
Ситуация же, когда нао держать в кеше два плана, параметризованый и с константой, выглядит довольно странно.

S> Или в MSSQL такое желание бессмысленно?

По моему глубокому убеждению и не только в MSSQL, а вообще где бы то ни было. Необходимость держать фиксированный план для какой-то константы — это первый звоночек о том, что возможно где-то косяк в базе.
... [ RSDN@Home 1.1.4 rev 0 ]
Мы уже победили, просто это еще не так заметно...
Re[17]: Кеширование и параметризация запросов
От: pkarklin  
Дата: 02.12.04 07:06
Оценка: +1
Здравствуйте, Merle, Вы писали:

M>До какого-то момента, как я уже писал, сервер одни и те же запросы, но с разными костантами воспринимает как разные запросы, а потом заменяет это дело на одни параметризованый.


Пожалйуста, подкрепите свои слова ссылками на BOL, MSDN, KB, наконец, собственный эксперимент.

Заранее благодарен, по жизни заблуждающийся pkarklin.
Re[21]: Кеширование и параметризация запросов
От: Igor Trofimov  
Дата: 02.12.04 11:20
Оценка: +1
iT>>А если у сервера есть гистограммы распределения?
iT>>И там написано, что константа1 встречается в таблице 10 раз, а константа2 — 1000000 раз?
M>Значит у него в кеше для данного запроса с параметрами(!) будет прописано, что возможно два физических плана выполнения в зависимости от того что пришло в параметре.

Мне кажется, что там это все "савсэм нэ так". В запросе с параметрами он эту статистику по значениям вообще использовать не сможет и будет прикидывать по средней статистике для всех значений.

А вот если будет два запроса с литералами, то с использованием гистограмм он получит и будет хранить два разных плана.
Re[8]: Кеширование и параметризация запросов
От: lazymf Россия  
Дата: 30.11.04 08:54
Оценка:
Здравствуйте, Softwarer, Вы писали:

S>В результате из его объяснений выяснилось, что MS SQL не поддерживает binding параметров в SQL-запросах, вот и вся причина — чтобы не парсить постоянно запрос, его приходится обертывать в хранимку.


Точно?
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Re[9]: Кеширование и параметризация запросов
От: Softwarer http://softwarer.ru
Дата: 30.11.04 09:05
Оценка:
Здравствуйте, lazymf, Вы писали:

L>Точно?


Могу дать ссылку на обсуждение — сам, извини, не проверял, так что передаю слова этого человека, на которые никто не возразил. То же ADO делает такую обертку автоматом — есть какая-то хранимка, что-то типа execute_sql, специально для этого предназначенная. А BDE, по его словам, просто поставляет значения параметров на клиенте.

P.S. Я тоже был здорово удивлен
Re[10]: Кеширование и параметризация запросов
От: lazymf Россия  
Дата: 30.11.04 09:32
Оценка:
Здравствуйте, Softwarer, Вы писали:

S>Могу дать ссылку на обсуждение — сам, извини, не проверял, так что передаю слова этого человека, на которые никто не возразил. То же ADO делает такую обертку автоматом — есть какая-то хранимка, что-то типа execute_sql, специально для этого предназначенная.


ADO при включенном Prepare насколько я помню юзает sp_prepexec/sp_execute. Всегда был уверен что это штатный механизм parameter binding, но только что открыл для себя что эти хранимые процедуры не описаны в BOL. Мнда, удивительное рядом, извиняюсь что встрял.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Re[11]: Кеширование и параметризация запросов
От: Softwarer http://softwarer.ru
Дата: 30.11.04 10:40
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Давай ссылку. Щас разберемся, кто там что у кого не поддерживает


Вот собственно тема — но ее вряд ли интересно читать целиком.

http://sql.ru/forum/actualthread.aspx?bid=20&amp;tid=126144&amp;pg=1&amp;hl=bind#995179

Поэтому приведу ссылки на несколько "ключевых" писем — может быть, субъективно выбранных.

http://sql.ru/forum/actualthread.aspx?bid=20&amp;tid=126144&amp;pg=3&amp;hl=bind#999124
http://sql.ru/forum/actualthread.aspx?bid=20&amp;tid=126144&amp;pg=3&amp;hl=bind#999500
http://sql.ru/forum/actualthread.aspx?bid=20&amp;tid=126144&amp;pg=3&amp;hl=bind#999551
http://sql.ru/forum/actualthread.aspx?bid=20&amp;tid=126144&amp;pg=3&amp;hl=bind#999558
http://sql.ru/forum/actualthread.aspx?bid=20&amp;tid=126144&amp;pg=3&amp;hl=bind#999592
http://sql.ru/forum/actualthread.aspx?bid=20&amp;tid=126144&amp;pg=4&amp;hl=bind#999631
http://sql.ru/forum/actualthread.aspx?bid=20&amp;tid=126144&amp;pg=4&amp;hl=bind#999910
http://sql.ru/forum/actualthread.aspx?bid=20&amp;tid=126144&amp;pg=4&amp;hl=bind#1000102
http://sql.ru/forum/actualthread.aspx?bid=20&amp;tid=126144&amp;pg=5&amp;hl=bind#1000335
http://sql.ru/forum/actualthread.aspx?bid=20&amp;tid=126144&amp;pg=5&amp;hl=bind#1000396
http://sql.ru/forum/actualthread.aspx?bid=20&amp;tid=126144&amp;pg=5&amp;hl=bind#1000529

Обратите внимание — человек даже сходу не поверил в трейс-файл от оракла, согласно которому запрос приходит на сервер без подстановки значений параметров вместо :1, :2.
Re[8]: Кеширование и параметризация запросов
От: wildwind Россия  
Дата: 30.11.04 10:43
Оценка:
Здравствуйте, Softwarer, Вы писали:

S>В результате из его объяснений выяснилось, что MS SQL не поддерживает binding параметров в SQL-запросах, вот и вся причина — чтобы не парсить постоянно запрос, его приходится обертывать в хранимку.


По-моему это прекратилось в SS 2000 — теперь кэшируется все, что парсится кем-либо и как-либо.
Re[9]: Кеширование и параметризация запросов
От: Softwarer http://softwarer.ru
Дата: 30.11.04 10:55
Оценка:
Здравствуйте, wildwind, Вы писали:

W>По-моему это прекратилось в SS 2000 — теперь кэшируется все, что парсится кем-либо и как-либо.


Хорошо если так. И очень плохо, что этого не было сразу. Правда, недавно мне рассказывали про collate в MS SQL — еще больше волосы дыбом встали

Собственно, мое впечатление следующее: профессионал должен работать со всем. То есть если что — надо будет работать именно с MS SQL. В то же время, если я вижу столь странные дырки — обычно я не трачу время на ознакомление со следующими версиями этой программы в надежде, что уж они-то будут хороши.
Re[10]: Кеширование и параметризация запросов
От: wildwind Россия  
Дата: 30.11.04 11:36
Оценка:
Здравствуйте, Softwarer, Вы писали:

S>Хорошо если так. И очень плохо, что этого не было сразу. Правда, недавно мне рассказывали про collate в MS SQL — еще больше волосы дыбом встали


Сейчас обещают, что все, что еще плохо, будет хорошо в Yukon .

S>В то же время, если я вижу столь странные дырки — обычно я не трачу время на ознакомление со следующими версиями этой программы в надежде, что уж они-то будут хороши.


Ну, в общем случае позиция спорная. Если бы все придерживались такого отношения, то ни один проект не смог бы встать крепко на ноги. (В Oracle тоже не все сразу появилось).
Re[12]: Кеширование и параметризация запросов
От: Sinclair Россия https://github.com/evilguest/
Дата: 30.11.04 11:38
Оценка:
Здравствуйте, Softwarer, Вы писали:
S>Вот собственно тема — но ее вряд ли интересно читать целиком.
О, спасибо.
S>http://sql.ru/forum/actualthread.aspx?bid=20&amp;tid=126144&amp;pg=1&amp;hl=bind#995179
S>Поэтому приведу ссылки на несколько "ключевых" писем — может быть, субъективно выбранных.
Ну, как только я дочитал до фрагмента (ссылки на этот форум ведут себя как-то странно, поэтому привожу цитату):

Блин, никто мне об этом не гоорил, я сам с этим сталкиваюсь. Если вернуться к приведенному выше примеру, то

SELECT
 *
FROM
  sysobjects
WHERE
  id = 2



и

SELECT
 *
FROM
  sysobjects
WHERE
  id = 123456



то это РАЗНЫЕ ЗАПРОСЫ. И чтоб иметь возможность повторного использования плана выполнения надо:

1. Или поместить этот запрос в хп.
2. Или завернуть его в sp_executesql, что в принципе равнзначно первому.

я понял, что товарищ с ником pkarklin, мягко говоря, заблуждается.
Мне сейчас недосуг листать BOL, но факт в том, что даже все константы MS SQL заменяет на искусственные переменные для того, чтобы брать план запроса из кэша.
Тем более это правда для биндинга параметров вида
SELECT
 *
FROM
  sysobjects
WHERE
  id = @id

Поэтому рассуждения о преимуществе ХП перед батчами — мифы, неподкрепленные реальными аргументами.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[13]: Кеширование и параметризация запросов
От: Softwarer http://softwarer.ru
Дата: 30.11.04 11:48
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>я понял, что товарищ с ником pkarklin, мягко говоря, заблуждается.


Насколько я в курсе, на sql.ru у него достаточно высокая репутация — я его знания оценить не в силах. Поэтому, предположу, вы скорее всего имеете в виду разные версии, разные настройки — просто потому, что оба производите впечатление компетентных специалистов.

Если вдруг решите это с ним обсудить — я с удовольствием почитаю. Он там присутствует постоянно, в частности, в форуме по MS SQL.
Re[11]: Кеширование и параметризация запросов
От: Softwarer http://softwarer.ru
Дата: 30.11.04 11:52
Оценка:
Здравствуйте, wildwind, Вы писали:

W>Ну, в общем случае позиция спорная. Если бы все придерживались такого отношения, то ни один проект не смог бы встать крепко на ноги. (В Oracle тоже не все сразу появилось).


Одно дело — "не появилось", а другое дело — "появившееся сделано плохо". Если первое — именно что вопрос времени (развития, итп), то второе — показывает некомпетентных специалистов либо наплевательский подход к результату, что скорее всего скажется и в следующих версиях.

Само собой, это не абсолют — скорее эвристика, которая помогает не утонуть в вариантах выбора. Если я что-то смотрел и мне не понравилось — я сначала посмотрю то, что еще не видел, и только потом, может быть, брошу второй взгляд на первый вариант.
Re[14]: Кеширование и параметризация запросов
От: Sinclair Россия https://github.com/evilguest/
Дата: 30.11.04 12:21
Оценка:
Здравствуйте, Softwarer, Вы писали:
S>Насколько я в курсе, на sql.ru у него достаточно высокая репутация — я его знания оценить не в силах. Поэтому, предположу, вы скорее всего имеете в виду разные версии, разные настройки — просто потому, что оба производите впечатление компетентных специалистов.
Все может быть. Кстати, занятный факт: в BOL по MS SQL 7.0 в разделе What's new присутствовали, в частности, слова о том, что теперь
а) план хранимой процедуры пересматривается при каждом выполнении дабы учесть все изменения
б) константы в запросе заменяются переменными для повышения вероятности cache hit
А теперь (2k) ничего этого нет. Зато есть невнятные упоминания о том, что использование процедур повышает производительность. А также замечания типа того, что использование не-fully qualified names предотвращает cache hit!

Резюме: похоже, надо ставить эксперименты. С включением трейс флагов (по которым тут эксперт — Merle) дабы отследить собственно, что, куда и где попадает.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[15]: Кеширование и параметризация запросов
От: Softwarer http://softwarer.ru
Дата: 30.11.04 12:34
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>а) план хранимой процедуры пересматривается при каждом выполнении дабы учесть все изменения


Хм. Имхо это будет дороговато.

S>б) константы в запросе заменяются переменными для повышения вероятности cache hit


В оракле есть соответствующий режим, но его не рекомендуется включать, чтобы эффективно использовать гистограммы. То есть идеальный подход выглядит как "переменные — параметрами, константы — константами". Это, естественно, подразумевает, что разработчик понимает, что делает, и не будет пихать константы туда, где нужен парамет.

S>А также замечания типа того, что использование не-fully qualified names предотвращает cache hit!


Хм. А в MS SQL есть понятие синонима? В Оракле есть момент, связанный с тем, что синонимы у разных пользователей могут относиться к разным объектам — и, соответственно, может потребоваться хранить и обсчитывать несколько планов для внешне одинаковых запросов.
Re[13]: Кеширование и параметризация запросов
От: Merle Австрия http://rsdn.ru
Дата: 30.11.04 22:30
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>я понял, что товарищ с ником pkarklin, мягко говоря, заблуждается.

Да он там по жизни заблуждается, да и вообще, sql.ru для здоровья читать — вредно, до обеда..

S> Мне сейчас недосуг листать BOL, но факт в том, что даже все константы MS SQL заменяет на искусственные переменные для того, чтобы брать план запроса из кэша.

Именно так. Там есть некоторое магическое число, количество запросов с константами до которого он константы воспринимает именно как константы, а после заменяет на один параметризованный запрос..
... [ RSDN@Home 1.1.4 rev 0 ]
Мы уже победили, просто это еще не так заметно...
Re[14]: Кеширование и параметризация запросов
От: Merle Австрия http://rsdn.ru
Дата: 30.11.04 22:30
Оценка:
Здравствуйте, Softwarer, Вы писали:

Поэтому, предположу, вы скорее всего имеете в виду разные версии, разные настройки — просто потому, что оба производите впечатление компетентных специалистов.
Нету там вообще никаких настроек, и различия в поведении от версий тоже нет.
... [ RSDN@Home 1.1.4 rev 0 ]
Мы уже победили, просто это еще не так заметно...
Re[16]: Кеширование и параметризация запросов
От: Merle Австрия http://rsdn.ru
Дата: 30.11.04 22:30
Оценка:
Здравствуйте, Softwarer, Вы писали:

S> То есть идеальный подход выглядит как "переменные — параметрами, константы — константами". Это, естественно, подразумевает, что разработчик понимает, что делает, и не будет пихать константы туда, где нужен парамет.

Идеальный подход для случая когда разработчик может заблуждаться применен у MSSQL'я. До какого-то момента, как я уже писал, сервер одни и те же запросы, но с разными костантами воспринимает как разные запросы, а потом заменяет это дело на одни параметризованый.

S>Хм. А в MS SQL есть понятие синонима?

Нет.
... [ RSDN@Home 1.1.4 rev 0 ]
Мы уже победили, просто это еще не так заметно...
Re[17]: Кеширование и параметризация запросов
От: Softwarer http://softwarer.ru
Дата: 01.12.04 07:34
Оценка:
Здравствуйте, Merle, Вы писали:

M>Идеальный подход для случая когда разработчик может заблуждаться применен у MSSQL'я. До какого-то момента, как я уже писал, сервер одни и те же запросы, но с разными константами воспринимает как разные запросы, а потом заменяет это дело на одни параметризованый.


А насколько дорого это обходится в случае, когда разработчик не заблуждается?

С парсингом при этом вроде бы все достаточно в порядке — нужен дополнительный хэш типа "сколько запросов с таким параметризованным видом сейчас в кэше" и все. Смущает другое: в ситуации, когда в принципе предусмотрено вытеснение из кэша (то есть я не могу выделить под планы столько места, чтобы они никогда не вытеснялись) сервер может решить параметризировать те запросы, которые я настоятельно хотел бы оставить с константами. Или в MSSQL такое желание бессмысленно?
Re[19]: Кеширование и параметризация запросов
От: fddima  
Дата: 01.12.04 18:00
Оценка:
Здравствуйте, Merle, Вы писали:

S>> Или в MSSQL такое желание бессмысленно?

M>По моему глубокому убеждению и не только в MSSQL, а вообще где бы то ни было. Необходимость держать фиксированный план для какой-то константы — это первый звоночек о том, что возможно где-то косяк в базе.
Я бы сказал что это колокол...
... << RSDN@Home 1.1.4 beta 3 rev. 231>>
Re[19]: Кеширование и параметризация запросов
От: Igor Trofimov  
Дата: 01.12.04 20:32
Оценка:
M>По моему глубокому убеждению и не только в MSSQL, а вообще где бы то ни было. Необходимость держать фиксированный план для какой-то константы — это первый звоночек о том, что возможно где-то косяк в базе.

А если у сервера есть гистограммы распределения?
И там написано, что константа1 встречается в таблице 10 раз, а константа2 — 1000000 раз?
Re[20]: Кеширование и параметризация запросов
От: Merle Австрия http://rsdn.ru
Дата: 01.12.04 21:13
Оценка:
Здравствуйте, Igor Trofimov, Вы писали:

iT>А если у сервера есть гистограммы распределения?

iT>И там написано, что константа1 встречается в таблице 10 раз, а константа2 — 1000000 раз?
Значит у него в кеше для данного запроса с параметрами(!) будет прописано, что возможно два физических плана выполнения в зависимости от того что пришло в параметре.
... [ RSDN@Home 1.1.4 rev 0 ]
Мы уже победили, просто это еще не так заметно...
Давайте по взрослому
От: Альт Россия http://cryptocode.ru
Дата: 02.12.04 06:55
Оценка:
Здравствуйте, Merle, Вы писали:

M>Здравствуйте, Igor Trofimov, Вы писали:


iT>>А если у сервера есть гистограммы распределения?

iT>>И там написано, что константа1 встречается в таблице 10 раз, а константа2 — 1000000 раз?
M>Значит у него в кеше для данного запроса с параметрами(!) будет прописано, что возможно два физических плана выполнения в зависимости от того что пришло в параметре.

Со ссылками на документацию и статьи в msdn.
Я не занимаюсь микрософтовским сиквелом, а работаю с ораклом и реально предствляю, что такое тьюнинг базы
Забавно читать про "умные" сервера. Выглядит совершенной отсебятиной.
: 4000654
Re: Давайте по взрослому
От: Sinclair Россия https://github.com/evilguest/
Дата: 02.12.04 07:21
Оценка:
Здравствуйте, Альт, Вы писали:

А>Со ссылками на документацию и статьи в msdn.

А>Я не занимаюсь микрософтовским сиквелом, а работаю с ораклом и реально предствляю, что такое тьюнинг базы
Да, мы все сочувствуем оракл-DBA
А>Забавно читать про "умные" сервера. Выглядит совершенной отсебятиной.
Merle щас на конференции. Вернется — надо попытаться склонить его к написанию статьи. А то вообще в среде СУБД-разработчиков ходит большое количество мифов. Самое противное в мифах об MS SQL то, что многие из них основываются на довольно-таки двусмысленных статьях в MSDN/BOL.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[19]: Кеширование и параметризация запросов
От: Softwarer http://softwarer.ru
Дата: 02.12.04 08:11
Оценка:
Здравствуйте, Merle, Вы писали:

M>Да практически ни на сколько. Задачи когда нужно держать отдельный план для какой-то константы встречаются крайне редко, и, как правило, решаются хинтами.


"Нужно" — не знаю, но "эффективнее" — бывает, и не так уж редко.

Что касается хинтов — у меня к ним отношение "использовать только если никак иначе не обойтись". Слишком уж неприятна вероятность того, что через какое-то время соотношения изменятся и хинт начнет резко тормозить там, где раньше ускорял.

M>Если запрос пользуется с константой, одной/двумя, то он так с этой константой в кеше и останется. А вот если запрос с константой, но при каждом новом запросе константа разная, то в какой-то момент сервер совершенно справедливо забъет на эти константы и начнет использовать параметры.


Это понятно. Но есть и промежуточный случай — когда этих констант, допустим, несколько десятков. Насколько я понимаю, должен быть какой-то критерий, начиная с которого сервер в принципе начинает "сворачивать" запросы — каков он?

M>Ситуация же, когда нао держать в кеше два плана, параметризованый и с константой, выглядит довольно странно.


Хм. С одной стороны — странно. С другой стороны, держать план "для значения 1", "для значения 2" и "для остальных значений" — может оказаться разумным.

M>Значит у него в кеше для данного запроса с параметрами(!) будет прописано, что возможно два физических плана выполнения в зависимости от того что пришло в параметре.


Хм. Ну это, простите, совершенно терминологический момент. Как именно сервер организовывает данные — его вопрос. Факт в том, что он держит в памяти несколько планов. А дальше идут мелочи и моменты, не оцениваемые на пальцах — например, сколько стоит отпарсить запрос (с целью замены константы параметрами) по сравнению с тратой памяти на хранение непараметризованных версий.
Re[18]: Кеширование и параметризация запросов
От: Sinclair Россия https://github.com/evilguest/
Дата: 02.12.04 09:05
Оценка:
Здравствуйте, pkarklin, Вы писали:

P>Пожалйуста, подкрепите свои слова ссылками на BOL, MSDN, KB, наконец, собственный эксперимент.

В доке по семерке упомянута эта возможность:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnsql7/html/queryproc.asp
(искать Automatic Parameters)
P>Заранее благодарен, по жизни заблуждающийся pkarklin.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[19]: Кеширование и параметризация запросов
От: pkarklin  
Дата: 02.12.04 09:19
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>В доке по семерке упомянута эта возможность:

S>http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnsql7/html/queryproc.asp
S>(искать Automatic Parameters)

Ага, упомянута. Вот тока не уточнено, для запросов какой сложности оптимизатор может автопараметризацию сделать. Зато в доке по 2000 нам раскрыли "страшную тайну". Читайте последний абзац:
здесь
Нивапрос.
От: Merle Австрия http://rsdn.ru
Дата: 02.12.04 09:35
Оценка:
Здравствуйте, Альт, Вы писали:

А>Я не занимаюсь микрософтовским сиквелом, а работаю с ораклом и реально предствляю, что такое тьюнинг базы

Здесь многие реально представляют что такое тюнинг базы..

А>Забавно читать про "умные" сервера.

Всегда полезно свой кругозор расширить, не Ораклом же единым, особенно учытывая что его оптимизатор весьма далек от совершенства...
... [ RSDN@Home 1.1.4 revision 0 ]
Мы уже победили, просто это еще не так заметно...
Re[20]: Кеширование и параметризация запросов
От: Sinclair Россия https://github.com/evilguest/
Дата: 02.12.04 09:43
Оценка:
Здравствуйте, pkarklin, Вы писали:

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

Ну, во-первых некто pkarklin уверял всех на sql.ru, что

SELECT * FROM  sysobjects WHERE id = 2

и
SELECT * FROM   sysobjects WHERE id = 123456


то это РАЗНЫЕ ЗАПРОСЫ.

P>Зато в доке по 2000 нам раскрыли "страшную тайну". Читайте последний абзац:
P>здесь
Во-вторых, не вижу там раскрытия тайны. Сказано лишь, что чем больше параметров, тем труднее сиквелу их выделить.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[20]: Кеширование и параметризация запросов
От: Merle Австрия http://rsdn.ru
Дата: 02.12.04 09:44
Оценка:
Здравствуйте, Softwarer, Вы писали:

S>Что касается хинтов — у меня к ним отношение "использовать только если никак иначе не обойтись". Слишком уж неприятна вероятность того, что через какое-то время соотношения изменятся и хинт начнет резко тормозить там, где раньше ускорял.

Совершенно согласен, но ведь и с фиксированными планами точно такая же ситуация, соотношение изменилось и данная константа уже отличается от других в противоположную сторону.

S>Это понятно. Но есть и промежуточный случай — когда этих констант, допустим, несколько десятков. Насколько я понимаю, должен быть какой-то критерий, начиная с которого сервер в принципе начинает "сворачивать" запросы — каков он?


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

S>Хм. Ну это, простите, совершенно терминологический момент. Как именно сервер организовывает данные — его вопрос. Факт в том, что он держит в памяти несколько планов. А дальше идут мелочи и моменты, не оцениваемые на пальцах — например, сколько стоит отпарсить запрос (с целью замены константы параметрами) по сравнению с тратой памяти на хранение непараметризованных версий.

ТАм на самом деле не совсем тривиальный механизм и кеш многоуровневый, я там примерно описал в соседнем посте, если будет время распишу еще подробнее...
... [ RSDN@Home 1.1.4 revision 0 ]
Мы уже победили, просто это еще не так заметно...
Re[19]: Кеширование и параметризация запросов
От: Sinclair Россия https://github.com/evilguest/
Дата: 02.12.04 09:55
Оценка:
Здравствуйте, Merle, Вы писали:

M>Здравствуйте, pkarklin, Вы писали:


P>>Пожалйуста, подкрепите свои слова ссылками на BOL, MSDN, KB, наконец, собственный эксперимент.

M>Да запросто, просто ход предыдущей дискуссии никаких ссылок на авторитетные источники не предполагал...
Ай малацца! А я уж тут не вытерпел — поковырялся... Правда, я про syscachedobjects ни сном ни духом до сих пор; потому помучил SQL Profiler.
В общем, заметил почти то же, что и ты, за исключением:
1. Сервер опознает тип параметра по размеру целой переменной; попробуй сделать where ...= 10000 и ты увидишь новую пару планов (в tinyint не влезет)
2. Не все запросы приезжают в кэш. Оба следующих не оставят о себе ни следа:
SELECT productID, total = SUM(UnitPrice)
FROM [order details]
GROUP BY productID
HAVING SUM(UnitPrice) > 40000

declare @p int
set @p=10
SELECT productID, total = SUM(UnitPrice)
FROM [order details]
GROUP BY productID
HAVING SUM(UnitPrice) > @p
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[21]: Кеширование и параметризация запросов
От: pkarklin  
Дата: 02.12.04 10:15
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, pkarklin, Вы писали:


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

S>Ну, во-первых некто pkarklin уверял всех на sql.ru, что
S>

S>

S>SELECT * FROM  sysobjects WHERE id = 2
S>

S>и
S>
S>SELECT * FROM   sysobjects WHERE id = 123456
S>


S>то это РАЗНЫЕ ЗАПРОСЫ.


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


P>>Зато в доке по 2000 нам раскрыли "страшную тайну". Читайте последний абзац:

P>>здесь
P>Во-вторых, не вижу там раскрытия тайны. Сказано лишь, что чем больше параметров, тем труднее сиквелу их выделить.

Вы, все-таки не совсем корректно переводите.

When processing complex SQL statements, the relational engine may have difficulty determining which expressions can be auto-parameterized.

Испытывать трудность — значит не принять решение об автопараметризации.Правда, количественных оценок не приведено.
Re[19]: Кеширование и параметризация запросов
От: pkarklin  
Дата: 02.12.04 10:26
Оценка:
Здравствуйте, Merle, Вы писали:

M>На самом деле в BOL или MSDN я ссылок на подробное объяснение механизма кеширования не припомню, мои знания берутся в основном из личного опыта и общения непосредственно с разработчиками SQL сервера.


Мои знания берутся тоже из личного опыта. И на, в принципе, классическом запросе вида Звезда, когда идет объединение порядка 10-15 таблиц и в предложение WHERE несколько критериев отбора как по полям целого типа, так и по datetime, оптимизатор не может провести автопараметризацию. О чем явно сказано в BOL. И именно для повторного использования плана выполнения в таких случаях, я использую хп. Хотя тем, кто любит зашивать инструкции в клиента, и sp_executesql подойдет.

M>Если интересно могу попросить у них ссылки на открытые источники в которых это описано, но не обещаю, что это будет быстро.. Ну вернемся к экспериментам.


Ссылки будут тока приветсвоваться. А на счет эксперимента...

Вы проекспериментировали на элементарном запросе, в котором сиквельный оптимизатор действительно сможет разобратья. В реальной жизни запросы куда по-сложнее.

M>Ясен хвост, что автоматически распознать что можно параметризовать, а что нельзя сиквел может далеко не всегда, поэтому очень приветствуется явное указание что именно мы хотим параметризовать.

M>И сделать это можно двумя способами, либо указывая вопросики и передавая параметры в должном порядке, либо используя процедуру sp_executesql, что и делают большинство клиентских библиотек.

Вот и я о том же твердил в том топике на SQL.RU, тока Вы еще третий способ забыли — использование хп.
Re[19]: Кеширование и параметризация запросов
От: Аноним  
Дата: 02.12.04 10:38
Оценка:
мда помнится пару лет назад мы это уже проходили — когда после игр с оракловым cursor_sharing выяснили что такие автоматы приносят только тормоза.
фишка в том что когда константу заменяют на на переменую меняется план, т.к. оптимайзер теперь не знает что может появится вместо переменной и например с джойном уже не знает какая таблица из 2х будет меньше и выбирает наихудший из возможных планов.
Re[20]: Кеширование и параметризация запросов
От: pkarklin  
Дата: 02.12.04 10:45
Оценка:
Здравствуйте, Аноним, Вы писали:

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



Тоже самое происходит и у сиквела в некотрых хп. Оптимизатор при отсутствии явного значения параметра выбирает не самый оптимальный план. В этом случаи такие хп приходиться писать WITH RECOMPILE.
Re[20]: Кеширование и параметризация запросов
От: Sinclair Россия https://github.com/evilguest/
Дата: 02.12.04 11:24
Оценка:
Здравствуйте, pkarklin, Вы писали:
P>Мои знания берутся тоже из личного опыта. И на, в принципе, классическом запросе вида Звезда, когда идет объединение порядка 10-15 таблиц и в предложение WHERE несколько критериев отбора как по полям целого типа, так и по datetime, оптимизатор не может провести автопараметризацию. О чем явно сказано в BOL. И именно для повторного использования плана выполнения в таких случаях, я использую хп. Хотя тем, кто любит зашивать инструкции в клиента, и sp_executesql подойдет.
А можно попросить пример (на базе Northwind или Pubs) такого запроса?
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[20]: Кеширование и параметризация запросов
От: Merle Австрия http://rsdn.ru
Дата: 02.12.04 11:26
Оценка:
Здравствуйте, pkarklin, Вы писали:
P>И на, в принципе, классическом запросе вида Звезда, когда идет объединение порядка 10-15 таблиц и в предложение WHERE несколько критериев отбора как по полям целого типа, так и по datetime, оптимизатор не может провести автопараметризацию.
Естественно автопараметризация не всесильна, но тех кто на клиенте запрос без параметров пишет бъют железной линейкой по пальцам и вообщем за дело.

P> И именно для повторного использования плана выполнения в таких случаях, я использую хп.

Если только для этого, то зря.

P> Хотя тем, кто любит зашивать инструкции в клиента, и sp_executesql подойдет.

sp_executesql подставляет драйвер, напрямую его никто не использует. На клиенте я пишу
using(DbManager DB = new DbManager())
{
     DataTable DT = DB.ExecteDataTable(@"
                seelect * from ... join ... on ... ...  where a=@a and b=@b",
                DB.Parameter("@a",1),
                DB.Parameter("@b",2));
}

А на сервер приезжает sp_executesql "...."

Так что грамотно написанный запрос, что в sp, что на клиенте кешируется с абсолютно одинаковой эффективностью.

P>Вот и я о том же твердил в том топике на SQL.RU, тока Вы еще третий способ забыли — использование хп.

Ээээ, "Я Пастернака не читал, но как и весь совецкий народ..."
Вообщем выводы озвученные здесь на основе Вашего sql.ru-шного топика имеют мало общего с действительностью, вот я и возмутился.
На самом деле, Вы, если я правильно понял, ратуете за использование хп на основании того, что они лучше кешируются? Для запросов с параметрами это не верно, в обоих случаях он кешируется одинаково хорошо.
... [ RSDN@Home 1.1.4 revision 0 ]
Мы уже победили, просто это еще не так заметно...
Re[20]: Кеширование и параметризация запросов
От: Softwarer http://softwarer.ru
Дата: 02.12.04 12:52
Оценка:
Здравствуйте, pkarklin, Вы писали:

M>>И сделать это можно двумя способами, либо указывая вопросики и передавая параметры в должном порядке, либо используя процедуру sp_executesql, что и делают большинство клиентских библиотек.

P>Вот и я о том же твердил в том топике на SQL.RU,

Простите, но в том топике на SQL.RU Вы ни слова не сказали про "указывая вопросики" — иначе тот топик был бы вдвое короче.
Re[21]: Кеширование и параметризация запросов
От: Softwarer http://softwarer.ru
Дата: 02.12.04 13:10
Оценка:
Здравствуйте, Merle, Вы писали:

M>Совершенно согласен, но ведь и с фиксированными планами точно такая же ситуация, соотношение изменилось и данная константа уже отличается от других в противоположную сторону.


Хм. Так фиксированных планов тоже никто не предлагает — по крайней мере, если не иметь в виду план, который год за годом остается в кэше, медленно теряя связь с реальностью

Ну а в целом ситуация понятна, спасибо.
Re[21]: Кеширование и параметризация запросов
От: pkarklin  
Дата: 02.12.04 13:25
Оценка:
Здравствуйте, Merle, Вы писали:

M>Естественно автопараметризация не всесильна, но тех кто на клиенте запрос без параметров пишет бъют железной линейкой по пальцам и вообщем за дело.


Хм...Понятно, но обыгрывалась то именно эта ситауция, а не параметризация на клиенте.

P>> И именно для повторного использования плана выполнения в таких случаях, я использую хп.

M>Если только для этого, то зря.

Нет, не только для этого.

M>sp_executesql подставляет драйвер, напрямую его никто не использует. На клиенте я пишу

...
M>А на сервер приезжает sp_executesql "...."

правильно, эту параметризацию выполняет клиентский механизм доступа к данным. И эта параметризация не имеет никакого отношения к автопараметризации оптимизатором, о чем и велась речь изначально.

M>Так что грамотно написанный запрос, что в sp, что на клиенте кешируется с абсолютно одинаковой эффективностью.


Согласен, тысячу раз согласен, при условии параметризации НА КЛИЕНТЕ.

M>На самом деле, Вы, если я правильно понял, ратуете за использование хп на основании того, что они лучше кешируются? Для запросов с параметрами это не верно, в обоих случаях он кешируется одинаково хорошо.


Нет, это тока одно из приемуществ при использовании хп.
Re[21]: Кеширование и параметризация запросов
От: pkarklin  
Дата: 02.12.04 13:27
Оценка:
Здравствуйте, Softwarer, Вы писали:

S>Здравствуйте, pkarklin, Вы писали:


M>>>И сделать это можно двумя способами, либо указывая вопросики и передавая параметры в должном порядке, либо используя процедуру sp_executesql, что и делают большинство клиентских библиотек.

P>>Вот и я о том же твердил в том топике на SQL.RU,

S>Простите, но в том топике на SQL.RU Вы ни слова не сказали про "указывая вопросики" — иначе тот топик был бы вдвое короче.


Простите, но про "указывая вопросики" — что означает клиентскую параметризацию при работе через ODBC с использованием модели prepare\execute, я писал.
Re[19]: Кеширование и параметризация запросов
От: Аноним  
Дата: 02.12.04 14:00
Оценка:
так может кто-нибудь повторить эксперемент на табличке где пара 7-ок, и почти милион 8-ок с запросом
select a from tbl1 where a<7
и
select a from tbl1 where a<8

так чтоб в в одном случае правильно было бы юзать индекс а в другом fullscan
Re[22]: Кеширование и параметризация запросов
От: Softwarer http://softwarer.ru
Дата: 02.12.04 14:06
Оценка:
Здравствуйте, pkarklin, Вы писали:

P>Простите, но про "указывая вопросики" — что означает клиентскую параметризацию при работе через ODBC с использованием модели prepare\execute, я писал.


Простите, в первую очередь я не понял, при чем тут ODBC. Сервер либо поддерживает binding в запросах, либо нет. Если поддерживает — Ваше утверждение о кэшировании планов исключительно в случае SP становится очень странным.

Во вторую очередь, если поиск не врет — слово odbc в той теме не употребляется ни разу вообще.

В-третьих, цитата:

Я:
----------------------------------------------------------------------------
А кто сказал, что оптимизатор должен строить план при каждом выполнении
запроса из приложения
----------------------------------------------------------------------------

Вы:
----------------------------------------------------------------------------
Блин, никто мне об этом не гоорил, я сам с этим сталкиваюсь.
----------------------------------------------------------------------------

В-третьих, когда я спросил Вас про "select .. where object_id = :id" Вы совершенно однозначно сказали, что для MS SQL это будут разные запросы — после чего долго удивлялись, что для оракла будет иначе.

P>Согласен, тысячу раз согласен, при условии параметризации НА КЛИЕНТЕ.


Хм. А какой вариант Вы рассматривали там? В форуме дельфы? Параметризацию не на клиенте?
Re[23]: Кеширование и параметризация запросов
От: pkarklin  
Дата: 02.12.04 14:28
Оценка:
Здравствуйте, Softwarer, Вы писали:

S>Простите, в первую очередь я не понял, при чем тут ODBC. Сервер либо поддерживает binding в запросах, либо нет. Если поддерживает — Ваше утверждение о кэшировании планов исключительно в случае SP становится очень странным.


Так, начинай с начала. Сам по себе оптимизатор ничего не поддерживает. За binding отвечают ДОПОЛНИТЕЛЬНЫЕ хп, sp_executesql, sp_prepare.


S>Во вторую очередь, если поиск не врет — слово odbc в той теме не употребляется ни разу вообще.


Видимо поиск врет, ибо вот цитата:


На счет вашей трассы. Если это действительно так и серверу Oracle передаются запросы с маркерами параметров и он сам их подставляет, то это плюс ему. Для сиквела параметризация маркеров происходит на уровне механизма доступа к данным (ODBC, OLEDB).


А вот пост: Оптимальней: куча QUERY или SQL.add(' ');


S>Хм. А какой вариант Вы рассматривали там? В форуме дельфы? Параметризацию не на клиенте?


Вернемся к тому топику еще раз? Разберемся снова в чем отличие параметризации клиентским механизмом доступа к данным и автопараметризацией оптимизатором сервера?
Re[24]: Кеширование и параметризация запросов
От: Merle Австрия http://rsdn.ru
Дата: 02.12.04 14:38
Оценка:
Здравствуйте, pkarklin, Вы писали:

P>Вернемся к тому топику еще раз? Разберемся снова в чем отличие параметризации клиентским механизмом доступа к данным и автопараметризацией оптимизатором сервера?

Стоп-стоп, не надо путать теплое с мягким. Есть автопараметризация — когда сервер сам догадывается о том, что константы можно заменить параметрами.
Есть просто параметризация, причем пофигу где она выполняется, на сервере или на клиенте, в данном случае where a=?, a=@a, и аa=:a полностью эквивалентны. Плюс есть еще некоторые системны хранимки, которые умеют немного больше.
... [ RSDN@Home 1.1.4 revision 0 ]
Мы уже победили, просто это еще не так заметно...
Re[25]: Кеширование и параметризация запросов
От: pkarklin  
Дата: 02.12.04 14:46
Оценка:
Здравствуйте, Merle, Вы писали:

M>Стоп-стоп, не надо путать теплое с мягким. Есть автопараметризация — когда сервер сам догадывается о том, что константы можно заменить параметрами.

M>Есть просто параметризация, причем пофигу где она выполняется, на сервере или на клиенте, в данном случае where a=?, a=@a, и аa=:a полностью эквивалентны. Плюс есть еще некоторые системны хранимки, которые умеют немного больше.

Ну, наконец, то. Хоть Вы меня поняли правильно. Т.е. резюмируя оба этих топика можно сказать, что использование хп — одно из возможных решений вопроса параметризации на сервере, а точнее решение проблем с автопарметризацией оптимизатором.
Re[24]: Кеширование и параметризация запросов
От: Softwarer http://softwarer.ru
Дата: 02.12.04 15:19
Оценка:
Здравствуйте, pkarklin, Вы писали:

Я позволю себе переупорядочить фразы — думаю, в этом нет ничего страшного.

P>Вернемся к тому топику еще раз? Разберемся снова в чем отличие параметризации клиентским механизмом доступа к данным и автопараметризацией оптимизатором сервера?


Нет, спасибо. С автопараметризацией все понятно — приезжает непараметризированный текст, сервер с ним более или менее успешно справляется. При этом неизбежны дополнительные накладные расходы (по сравнению с ХП) на многократный парсинг текста.

В рамках изначального вопроса — тема практически неинтересная.

P>Видимо поиск врет, ибо вот цитата:


Джуджу уже отписал. Интересный глюк.

P>Так, начинай с начала. Сам по себе оптимизатор ничего не поддерживает. За binding отвечают ДОПОЛНИТЕЛЬНЫЕ хп, sp_executesql, sp_prepare.


Я окончательно перестал Вас понимать. Давайте я попробую сформулировать вопрос, ответ на который меня интересует.

Исходная ситуация: я в дельфе делаю объект Query (или аналогичный в другой технологии доступа), пишу в нем SQL.Text = 'select * from table where field = :a', указываю значение для параметра, делаю Open.

Вопрос: какие варианты реально возможны в случае MS SQL?

1) На сервер приедет текст запроса вида (примерно) 'select * from table where field = ?' и значение параметра.

2) На сервер приедет текст запроса вида 'select * from table where field = 123' (с подставленным параметром)

3) На сервер приедет (в каком-то виде) просьба вызвать хранимку (sp_XXXX) с указанными параметрами, одним из которых является текст sql.

4) Еще что-то
Re[25]: Кеширование и параметризация запросов
От: pkarklin  
Дата: 02.12.04 15:32
Оценка:
Здравствуйте, Softwarer, Вы писали:

S>Я окончательно перестал Вас понимать. Давайте я попробую сформулировать вопрос, ответ на который меня интересует.


S>Исходная ситуация: я в дельфе делаю объект Query (или аналогичный в другой технологии доступа), пишу в нем SQL.Text = 'select * from table where field = :a', указываю значение для параметра, делаю Open.


S>Вопрос: какие варианты реально возможны в случае MS SQL?


S>1) На сервер приедет текст запроса вида (примерно) 'select * from table where field = ?' и значение параметра.


S>2) На сервер приедет текст запроса вида 'select * from table where field = 123' (с подставленным параметром)


S>3) На сервер приедет (в каком-то виде) просьба вызвать хранимку (sp_XXXX) с указанными параметрами, одним из которых является текст sql.


S>4) Еще что-то


Очень многое будет зависеть от того, какие дрова вы будете использовать. При работе с BDE и Prepared = False будет 2.

1 не будет никогда, ибо '?' — это маркер параметра для ODBC функции SQLPrepare. При этом на сервер при первом вызове будет отправлен вызов sp_prepare, где будет текст запроса и параметр вида @param. А уже затем sp_execute c параметром.

При работе через ADO (OLEDB) и использовании наследников TCustomADODataSet будет произведен вызов sp_executesql примерно в таком виде:


execute sp_executesql 
          N'select * from pubs.dbo.employee where job_lvl = @level',
          N'@level tinyint',
          @level = 35
Re[25]: Кеширование и параметризация запросов
От: lazymf Россия  
Дата: 03.12.04 04:35
Оценка:
Здравствуйте, Softwarer, Вы писали:

S>Исходная ситуация: я в дельфе делаю объект Query (или аналогичный в другой технологии доступа), пишу в нем SQL.Text = 'select * from table where field = :a', указываю значение для параметра, делаю Open.

S>Вопрос: какие варианты реально возможны в случае MS SQL?

Ну так посмотри в SQL Profiler. Ну вот например что происходит если делать аналогичное в VB6 + ADO.

Dim cnn As New ADODB.Connection
Dim cmd As New ADODB.Command, prm As ADODB.Parameter, rst As ADODB.Recordset

cnn.Open "Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=mydb;Data Source=myserv"

Set cmd.ActiveConnection = cnn
cmd.CommandType = adCmdText
cmd.CommandText = "SELECT * FROM mytable WHERE mytableid = ?"
cmd.Prepared = True

Set prm = cmd.CreateParameter("prm1", adInteger, adParamInput)
cmd.Parameters.Append prm

cmd.Parameters(0).Value = 5
Set rst = cmd.Execute


В этом месте видим в профайлере (одним батчем):

declare @P1 int
set @P1=1
exec sp_prepexec @P1 output, N'@P1 int', N'SELECT * FROM mytable WHERE mytableid = @P1', 5
select @P1


Идем дальше:

rst.Close
cmd.Parameters(0).Value = 10005
Set rst = cmd.Execute


В профайлере:

exec sp_execute 1, 10005


Ты что-то такое хотел увидеть?
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Re[26]: Кеширование и параметризация запросов
От: Softwarer http://softwarer.ru
Дата: 03.12.04 07:31
Оценка:
Здравствуйте, pkarklin, Вы писали:

Спасибо. То есть, картина в моем понимании остается примерно неизменной: либо SQL обертывается в хранимки (явно или неявно — механизмом доступа), либо подстановка параметров на клиенте и соответствующая некоторая потеря производительности.

Здравствуйте, lazymf, Вы писали:

L>Ну так посмотри в SQL Profiler. Ну вот например что происходит если делать аналогичное в VB6 + ADO.


Боюсь, даже если я поставлю себе MS SQL — результаты, полученные мной "при первом знакомстве" вряд ли можно будет считать достоверными характеристиками продукта. Поэтому приходится спрашивать.

О том, что описанный Вами вариант возможен, pkarklin уже говорил. Меня интересует спектр возможностей — в первую очередь, упоминание "вопросиков" заставило предположить, что в MS SQL таки возможен, как в Оракле, первый из названных мной вариантов.
Re[27]: Кеширование и параметризация запросов
От: Merle Австрия http://rsdn.ru
Дата: 03.12.04 07:43
Оценка:
Здравствуйте, Softwarer, Вы писали:

S> Меня интересует спектр возможностей — в первую очередь, упоминание "вопросиков" заставило предположить, что в MS SQL таки возможен, как в Оракле, первый из названных мной вариантов.

Возможен, все зависит от драйвера. Просто использование системных хранимок типа sp_executesql несколько эффективнее и все последние версии драйверов пользуются ими.
... [ RSDN@Home 1.1.4 revision 0 ]
Мы уже победили, просто это еще не так заметно...
Re[28]: Кеширование и параметризация запросов
От: Softwarer http://softwarer.ru
Дата: 03.12.04 08:10
Оценка:
Здравствуйте, Merle, Вы писали:

M>Возможен, все зависит от драйвера. Просто использование системных хранимок типа sp_executesql несколько эффективнее и все последние версии драйверов пользуются ими.


А за счет чего эффективнее? Или просто известно по факту?

Что я не совсем понимаю — если есть эффективная реализация, что мешает серверу вызывать ее внутри себя? Дополнительные телодвижения клиента, имхо, заведомо не более эффективны — он снаружи, то есть не может использовать то, что сервер может сделать внутри себя.
Re[29]: Кеширование и параметризация запросов
От: Merle Австрия http://rsdn.ru
Дата: 03.12.04 08:29
Оценка:
Здравствуйте, Softwarer, Вы писали:

S>А за счет чего эффективнее? Или просто известно по факту?

Скорее по факту, но есть некоторые догадки...

S>Что я не совсем понимаю — если есть эффективная реализация, что мешает серверу вызывать ее внутри себя?

Видимо сервер не всегда в состоянии привести оддну реализацию к другой.

S>Дополнительные телодвижения клиента, имхо, заведомо не более эффективны — он снаружи, то есть не может использовать то, что сервер может сделать внутри себя.

Это не дополнительные телодвижения, клиент может вызвать либо одну реализацию, либо другую. Накладные расходы на клиенте на приведение к обоим формам вызова примерно одинаковы.
Видимо, в силу каких-то причин, серверу проще, когда параметры явно проименованы и заранее известен их тип, клиенту все равно, а серверу проще...
... [ RSDN@Home 1.1.4 revision 0 ]
Мы уже победили, просто это еще не так заметно...
Re[30]: Кеширование и параметризация запросов
От: Sinclair Россия https://github.com/evilguest/
Дата: 03.12.04 09:15
Оценка:
Здравствуйте, Merle, Вы писали:
S>>Дополнительные телодвижения клиента, имхо, заведомо не более эффективны — он снаружи, то есть не может использовать то, что сервер может сделать внутри себя.
M>Это не дополнительные телодвижения, клиент может вызвать либо одну реализацию, либо другую. Накладные расходы на клиенте на приведение к обоим формам вызова примерно одинаковы.
M>Видимо, в силу каких-то причин, серверу проще, когда параметры явно проименованы и заранее известен их тип, клиенту все равно, а серверу проще...
Ну, на самом деле проблема упирается ровно в парсер.
Смысл в том, что явное указание параметров точно говорит движку, какие части запроса имеют тенденцию измениться при следующем запуске. Если их нет, то для парсера весь запрос — это просто строка. Вот простейший пример:
select * from orders where orderdate < DateAdd(day, -5, getdate())

Сколько здесь параметров? один? два? Какой план кэшировать?
select * from orders where orderdate < @p1

или
select * from orders where orderdate < DateAdd(day, @p1, getdate())

или может
select * from orders where orderdate < DateAdd(day, @p1, @p2)

?
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[31]: Кеширование и параметризация запросов
От: Softwarer http://softwarer.ru
Дата: 03.12.04 09:46
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Смысл в том, что явное указание параметров точно говорит движку, какие части запроса имеют тенденцию измениться при следующем запуске. Если их нет, то для парсера весь запрос — это просто строка. Вот простейший пример:


Не думал о столь интересном примере — но в целом именно то, что я имел в виду.

Получив такой запрос, сервер сможет принять в общем случае более грамотное решение, нежели клиент, и принять его эффективнее. Почему грамотное — понятно, у сервера есть куча дополнительной информации. Почему эффективнее — потому что ему доступно все то же, что и клиенту, и еще много того, чего у клиента нет.

Клиент, получив указанный запрос, может либо прямо передать его на сервер, либо передать, как-то обработав (в частности, обернув в хранимки). Если у клиента есть выбор — ему придется, например, отпарсить запрос, определить, есть ли в нем параметры, и далее либо передать текст, либо сформировать вызов хранимок. Стоит отметить, что даже в рамках многократного повторения запроса в сеансе — клиенту потребуется либо держать собственный кэш запросов, либо многократно выполнять эту операцию (я не имею в виду вариант, когда клиент может сохранять хандл запроса).

Если то же делать на сервере — прежде всего, сервер сможет эффективно определить, что он это уже делал в рамках такого же запроса с другого клиента. Если эта проверка не прошла — сервер все равно должен делать парсинг, то есть никаких дополнительных расходов. И дальше — если нужно, он может начать думать, какой из приведенных Вами вариантов лучше, причем думать, основываясь на информации (например — детерминированы ли указанные функции).
Re[32]: Кеширование и параметризация запросов
От: pkarklin  
Дата: 03.12.04 10:11
Оценка:
Здравствуйте, Softwarer, Вы писали:

S>Получив такой запрос, сервер сможет принять в общем случае более грамотное решение, нежели клиент, и принять его эффективнее. Почему грамотное — понятно, у сервера есть куча дополнительной информации. Почему эффективнее — потому что ему доступно все то же, что и клиенту, и еще много того, чего у клиента нет.


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

S>Клиент, получив указанный запрос, может либо прямо передать его на сервер, либо передать, как-то обработав (в частности, обернув в хранимки). Если у клиента есть выбор — ему придется, например, отпарсить запрос, определить, есть ли в нем параметры, и далее либо передать текст, либо сформировать вызов хранимок. Стоит отметить, что даже в рамках многократного повторения запроса в сеансе — клиенту потребуется либо держать собственный кэш запросов, либо многократно выполнять эту операцию (я не имею в виду вариант, когда клиент может сохранять хандл запроса).


Никакого парсера и кэша на клиенте нет и быть не может. Клиентский механизм доступа — это всего лишь промежуточное звено. Если говорить в контексте работы с дельфи, то маркеры параметров преобразуються в объекты коллеции Parameters ADO, потом идет мапирование этих объектов в интерфейсы OLEDB, которое в конечном итоге и оформляет вызов sp_executesql с необходимыми параметрами.

S>Если то же делать на сервере — прежде всего, сервер сможет эффективно определить, что он это уже делал в рамках такого же запроса с другого клиента. Если эта проверка не прошла — сервер все равно должен делать парсинг, то есть никаких дополнительных расходов. И дальше — если нужно, он может начать думать, какой из приведенных Вами вариантов лучше, причем думать, основываясь на информации (например — детерминированы ли указанные функции).


Опять же, не всегда сервер это может определить. Именно для этого и существует набор системных хранимок, реализующих модель prepare\execute — т.е. гарантированное повторное использование планов выполнения.
Re[32]: Кеширование и параметризация запросов
От: Sinclair Россия https://github.com/evilguest/
Дата: 03.12.04 10:16
Оценка:
Здравствуйте, Softwarer, Вы писали:

S>Получив такой запрос, сервер сможет принять в общем случае более грамотное решение, нежели клиент, и принять его эффективнее. Почему грамотное — понятно, у сервера есть куча дополнительной информации. Почему эффективнее — потому что ему доступно все то же, что и клиенту, и еще много того, чего у клиента нет.

Я пока не вижу никаких способов для сервера принять "более грамотное рещение". Можно на пальцах объяснить "ход мысли алгоритма"?
S>Клиент, получив указанный запрос, может либо прямо передать его на сервер, либо передать, как-то обработав (в частности, обернув в хранимки).
Гм. Клиент вообще-то не "получает", а "порождает" запросы. На то он и клиент.
S>Если у клиента есть выбор — ему придется, например, отпарсить запрос, определить, есть ли в нем параметры, и далее либо передать текст, либо сформировать вызов хранимок. Стоит отметить, что даже в рамках многократного повторения запроса в сеансе — клиенту потребуется либо держать собственный кэш запросов, либо многократно выполнять эту операцию (я не имею в виду вариант, когда клиент может сохранять хандл запроса).
Я не очень понимаю, зачем клиенту держать собственный кэш запросов. Нам приходилось реализовывать такую штуку, но там речь шла о framework, или прослойке между собственно прикладным кодом и сервером, которая и отвечала за автоматическое сопоставление текста запроса и кэша.
S>Если то же делать на сервере — прежде всего, сервер сможет эффективно определить, что он это уже делал в рамках такого же запроса с другого клиента.
Гм. Основной вопрос — это смысл выражения "он это уже делал". Есть очень-очень много вариантов сопоставления двух запросов. И тут появляется тонкость: примитивный алгоритм сравнения не "поймает" запросы, к которым бы подошел один план, а умный рискует проработать дольше, чем оптимизатор при построении плана с нуля. Типичный tradeoff.
S>Если эта проверка не прошла — сервер все равно должен делать парсинг, то есть никаких дополнительных расходов. И дальше — если нужно, он может начать думать, какой из приведенных Вами вариантов лучше, причем думать, основываясь на информации (например — детерминированы ли указанные функции).
Вот тут я еще раз попрошу прокомментировать ход мыслей потенциального оптимизатора, связанных с детерминированностью этой функции, при выборе параметризуемых частей?
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[33]: Кеширование и параметризация запросов
От: Softwarer http://softwarer.ru
Дата: 03.12.04 10:58
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Я пока не вижу никаких способов для сервера принять "более грамотное рещение". Можно на пальцах объяснить "ход мысли алгоритма"?


Хм. В первую очередь — я не вижу для клиента возможности сделать что-то лучше сервера.

Замечание: похоже, наметилось некоторое терминологическое непонимание. Под "клиентом" я имею в виду софт, работающий на клиентской машине и являющийся прослойкой между сервером и клиентским приложением — например, те же BDE/ADO/ODBC. Я не имею в виду, например, программиста, разрабатывающего клиентское приложение.

S>Гм. Основной вопрос — это смысл выражения "он это уже делал". Есть очень-очень много вариантов сопоставления двух запросов. И тут появляется тонкость: примитивный алгоритм сравнения не "поймает" запросы, к которым бы подошел один план, а умный рискует проработать дольше, чем оптимизатор при построении плана с нуля. Типичный tradeoff.


Безусловно. Но если разработчики сервера могут здесь выбрать оптимальный алгоритм — разработчик "клиентской прослойки" такой возможности практически лишен; он может либо "тупо передать текст SQL на сервер", либо практически обязан парсить его каждый раз, чтобы "передавать не тупо".

Это напоминает мне JDK, где Statement и PreparedStatement — разные понятия, работа с которыми существенно разнится. Но там хоть программист выбирает решение при разработке — а здесь клиент, получив текст SQL от приложения, должен выбрать, то ли посылать так, то ли организовывать подстановку параметров...

S>Вот тут я еще раз попрошу прокомментировать ход мыслей потенциального оптимизатора, связанных с детерминированностью этой функции, при выборе параметризуемых частей?


Детерминированность (понятие, кстати, тоже можно понимать по-разному) — определяет, насколько можно "вынести" вызов функции "наружу" относительно блока, в котором она употребляется — согласны? Недетерминированная функция в общем случае не может быть заменена "цельным параметром", как в первом из Ваших примеров — например, в вариантах

select random(1000)*field from table

select log(1000)*field from table


сервер может существенно оптимизировать второй, в то время как "клиентская прослойка" не имеет для этого информации (по крайней мере если функции — пользовательские, а не стандартные серверные).

Дальше гипотетически начинаются более интересные моменты. Если известна гистограмма распределения результатов функции — оптимизатор может ее учесть, в том числе решить "выносить функцию наружу или бессмысленно", в том числе "ставить ли план в зависимость от результата функции".

Например, если брать Ваш пример с датской функцией — сервер должен решить, будет ли он пользоваться индексом или full table scan. То есть в варианте "< @p1" сервер в принципе может вычислить p1 и на его основании выбрать тот или иной план, это, соответственно, повышает привлекательность такого варианта параметризации. С другой стороны, если такой информации нет — серверу может показаться более интересным воспользоваться планом для четвертого варианта, поскольку он потенциально "максимально кэширумый".
Re[33]: Кеширование и параметризация запросов
От: Softwarer http://softwarer.ru
Дата: 03.12.04 11:07
Оценка:
Здравствуйте, pkarklin, Вы писали:

P>В том то и дело, что сервер не всегда может принять грамотное решение о замене статических значений параметрами.

P>И эту часть в большинстве случаев приходиться решать или с помощью хп, или с помощью явной парамтеризации на клиенте.

Само собой. Именно поэтому вариант, когда софт не проявляет самодеятельности, мне и нравится больше остальных

P>Никакого парсера и кэша на клиенте нет и быть не может. Клиентский механизм доступа — это всего лишь промежуточное звено. Если говорить в контексте работы с дельфи, то маркеры параметров преобразуються в объекты коллеции Parameters ADO, потом идет мапирование этих объектов в интерфейсы OLEDB, которое в конечном итоге и оформляет вызов sp_executesql с необходимыми параметрами.


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

P>Опять же, не всегда сервер это может определить. Именно для этого и существует набор системных хранимок, реализующих модель prepare\execute — т.е. гарантированное повторное использование планов выполнения.


Я только не понимаю, нафига для этого хранимки, если честно. Модель prepare/execute в них совершенно не нуждается. Собственно, такое впечатление, что хранимки появились для обхода самодеятельности сервера в плане автопараметризации.
Re[34]: Кеширование и параметризация запросов
От: Merle Австрия http://rsdn.ru
Дата: 03.12.04 11:41
Оценка:
Здравствуйте, Softwarer, Вы писали:

S>Безусловно. Но если разработчики сервера могут здесь выбрать оптимальный алгоритм — разработчик "клиентской прослойки" такой возможности практически лишен; он может либо "тупо передать текст SQL на сервер", либо практически обязан парсить его каждый раз, чтобы "передавать не тупо".

Что-то тут опять какой-то мисандерстундинг наметился.
Допустим клиент пишет:
  DB.Execute("select ... where a=@a and b=@b", DB.Parameter("@a", 1), DB.Parameter("@b", 2));

Далее драйвер может передать на сервер:
1. "select .... where a=? and b=?", 1,2
либо
2. sp_execute "select .... where a=? and b=?", @a int, @b int, 1, 2
Для клиента (драйвера) затраты на реализацию обоих вариантов идентичны, разница в синтаксисе, для сервера вариант 2 предпочтительнее...

S>Это напоминает мне JDK, где Statement и PreparedStatement — разные понятия, работа с которыми существенно разнится. Но там хоть программист выбирает решение при разработке — а здесь клиент, получив текст SQL от приложения, должен выбрать, то ли посылать так, то ли организовывать подстановку параметров...

Бррр... Что значит "посылать так"? Если программист клиентского приложения указал константы, значит приедут константы, драйвер тут ничего не сделает, если же программист указал параметры, то приедут параметры, вопрос только в каком виде. При этом для драйвера это, по большей части, всего лишь вопрос синтаксиса.
... [ RSDN@Home 1.1.4 revision 0 ]
Мы уже победили, просто это еще не так заметно...
Re[34]: Кеширование и параметризация запросов
От: pkarklin  
Дата: 03.12.04 11:55
Оценка:
Здравствуйте, Softwarer, Вы писали:

S>Здравствуйте, pkarklin, Вы писали:


S>Для того, чтобы найти и преобразовать маркеры, уже необходим парсер, практически такой же, как и на сервере (надеюсь, мы различаем парсер и синтаксический анализатор?).


Да нет же, парсер на клиенте, который заменяет :param_name (как это делают наследники TDataSet в Delphi) или ?, как это делает ODBC очень прост.

S>Я только не понимаю, нафига для этого хранимки, если честно. Модель prepare/execute в них совершенно не нуждается. Собственно, такое впечатление, что хранимки появились для обхода самодеятельности сервера в плане автопараметризации.


Модель prepare\execute была создана для Ad hoc запросов с клиента,в то время как план выполнения хп заведомо будет кэшироваться и повторно использоваться.
Re[20]: Кеширование и параметризация запросов
От: Sinclair Россия https://github.com/evilguest/
Дата: 03.12.04 11:59
Оценка:
Здравствуйте, <Аноним>, Вы писали:
А>так чтоб в в одном случае правильно было бы юзать индекс а в другом fullscan
В таком простом случае выбора просто нет. Рассмотри пример с двумя параметрами:
select * from people where occupation = "Programmer" and Gender = @Male

и select * from peope where occupation = "Manager" and Gender=@Male

Предполагаем, что в среднем количество мужчин и женщин одинаково, программеров примерно 1%, менеджеров — 70%. Есть индексы по Occupation и по Gender.
В первом случае очевидно имеет смысл сделать index seek по Occupation, а затем bookmark lookup и filter по Gender. (дорогой фильтр применится к 1% от общего количества записей).
Во втором случае имеет смысл наоборот, сделать index seek по Gender=@male, т.к. фильтровать 50% от N выгоднее, чем 70% от N.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[34]: Кеширование и параметризация запросов
От: Sinclair Россия https://github.com/evilguest/
Дата: 03.12.04 11:59
Оценка:
Здравствуйте, Softwarer, Вы писали:
S>Замечание: похоже, наметилось некоторое терминологическое непонимание. Под "клиентом" я имею в виду софт, работающий на клиентской машине и являющийся прослойкой между сервером и клиентским приложением — например, те же BDE/ADO/ODBC. Я не имею в виду, например, программиста, разрабатывающего клиентское приложение.
А-а, вот оно в чем дело. Ну, вообще-то речь вроде бы не шла об автопараметризации в этой прослойке.
S>Безусловно. Но если разработчики сервера могут здесь выбрать оптимальный алгоритм — разработчик "клиентской прослойки" такой возможности практически лишен; он может либо "тупо передать текст SQL на сервер", либо практически обязан парсить его каждый раз, чтобы "передавать не тупо".
Гм. Тут есть некоторая неясность с "парсить каждый раз". Я не очень понимаю, откуда у прослойки берется выбор. Ей уже дали параметризованный запрос. Можно, конечно, выполнить подстановку (как это делает BDE — по словам pkarklin), или добиться того, чтобы на сервер уехал запрос с уже заданными пользователем параметрами.
S>Это напоминает мне JDK, где Statement и PreparedStatement — разные понятия, работа с которыми существенно разнится. Но там хоть программист выбирает решение при разработке — а здесь клиент, получив текст SQL от приложения, должен выбрать, то ли посылать так, то ли организовывать подстановку параметров...
Где "здесь"??? Я что-то вообще нить потерял. ADO/BDE/ODBC/OLE DB ничем не отличаются от JDK. Точно также программист выбирает, что будет параметризовываться.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[35]: Кеширование и параметризация запросов
От: Softwarer http://softwarer.ru
Дата: 03.12.04 12:10
Оценка:
Здравствуйте, Merle, Вы писали:

M>Для клиента (драйвера) затраты на реализацию обоих вариантов идентичны, разница в синтаксисе, для сервера вариант 2 предпочтительнее...


Имхо идеальный вариант — когда драйвер передает на сервер информацию типа

"select .... where a=? and b=?", 1 int,2 int


Ну а дальше сервер вызывает тот модуль, который вызвал бы при приходе вызова ХП (я правильно понимаю, что это ХП?)sp_execute.

M>Бррр... Что значит "посылать так"? Если программист клиентского приложения указал константы, значит приедут константы, драйвер тут ничего не сделает, если же программист указал параметры, то приедут параметры, вопрос только в каком виде. При этом для драйвера это, по большей части, всего лишь вопрос синтаксиса.


Ээ.. следующую цитату plarklin я понял как то, что "параметры, не обернутые в вызов хранимки, не приедут никогда".

------------------------------------------------------------------------------------------------------------------
1 не будет никогда, ибо '?' — это маркер параметра для ODBC функции SQLPrepare. При этом на сервер при первом вызове будет отправлен вызов sp_prepare, где будет текст запроса и параметр вида @param. А уже затем sp_execute c параметром.
------------------------------------------------------------------------------------------------------------------

Я неправ? Как это следует понимать?
Re[36]: Кеширование и параметризация запросов
От: pkarklin  
Дата: 03.12.04 12:15
Оценка:
Здравствуйте, Softwarer, Вы писали:

S>Ээ.. следующую цитату plarklin я понял как то, что "параметры, не обернутые в вызов хранимки, не приедут никогда".


S>------------------------------------------------------------------------------------------------------------------

S>1 не будет никогда, ибо '?' — это маркер параметра для ODBC функции SQLPrepare. При этом на сервер при первом вызове будет отправлен вызов sp_prepare, где будет текст запроса и параметр вида @param. А уже затем sp_execute c параметром.
S>------------------------------------------------------------------------------------------------------------------

S>Я неправ? Как это следует понимать?


Правильно вы поняли. Не знает парсер сиквела что есть "?".
Re[35]: Кеширование и параметризация запросов
От: Softwarer http://softwarer.ru
Дата: 03.12.04 12:17
Оценка:
Здравствуйте, pkarklin, Вы писали:

P>Да нет же, парсер на клиенте, который заменяет :param_name (как это делают наследники TDataSet в Delphi) или ?, как это делает ODBC очень прост.


Тот парсер, который в наследнике TDataSet, еще и весьма глючен — что иллюстрирует последствия этой простоты.

Он действительно прост — как прост и на сервере. Но тем не менее, он работает очень долго по сравнению с поиском в кэше отпарсенного запроса. То есть вариант:

1. На сервер приехал текст SQL
2. Текст ищется в кэше
3. При отсутствии — парсится, анализируется, строится план

эффективнее, нежели

0. Текст SQL преобразовывается "простым парсером"
1. ---
2. ---
3. ---

S>>Я только не понимаю, нафига для этого хранимки, если честно. Модель prepare/execute в них совершенно не нуждается. Собственно, такое впечатление, что хранимки появились для обхода самодеятельности сервера в плане автопараметризации.

P>Модель prepare\execute была создана для Ad hoc запросов с клиента,в то время как план выполнения хп заведомо будет кэшироваться и повторно использоваться.

Модель prepare/execute, по моим представлениям, появилась раньше понятия "хранимка" Я понял Ваше утверждение так, что в MSSQL ее можно реализовать только с помощью хранимок же (sp_prepare, sp_execute). Я неправильно понял? Как оно?
Re[35]: Кеширование и параметризация запросов
От: Softwarer http://softwarer.ru
Дата: 03.12.04 12:23
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Гм. Тут есть некоторая неясность с "парсить каждый раз". Я не очень понимаю, откуда у прослойки берется выбор. Ей


Это растет из фразы Merle о том, что варианты с приходом "просто sql" и "sp_execute sql" различны по эффективности и сервер в общем случае не может преобразовать менее эффективный вариант в более эффективный.

Если не может — значит, клиент должен в какой-то ситуации посылать одно, в какой-то ситуации — другое, делая выбор на основании чего-то.
Re[37]: Кеширование и параметризация запросов
От: Softwarer http://softwarer.ru
Дата: 03.12.04 12:28
Оценка:
Здравствуйте, pkarklin, Вы писали:

P>Правильно вы поняли. Не знает парсер сиквела что есть "?".


Тогда я попросил бы Вас с Merle прийти к единому мнению по этому вопросу. Насколько я понимаю, сейчас, говоря о передаче параметризованного запроса с клиента:

— Вы говорите, что возможен только вариант с хранимкой
— Merle говорит, что вариант без хранимки возможен, но менее эффективен.

Собственно, меня удивляют оба варианта, но хотелось бы знать "как оно есть на самом деле".
Re[38]: Кеширование и параметризация запросов
От: pkarklin  
Дата: 03.12.04 12:38
Оценка:
Здравствуйте, Softwarer, Вы писали:


S>- Вы говорите, что возможен только вариант с хранимкой

S>- Merle говорит, что вариант без хранимки возможен, но менее эффективен.

S>Собственно, меня удивляют оба варианта, но хотелось бы знать "как оно есть на самом деле".


Давайте опять разбираться с терминологией. Хранимки реализующие модель prepare\execute ODBC (sp_prepare, sp_execute, sp_uprepare) и хранимка sp_executesql — это системные хранимки. И они на писаны не на T-SQL, в отличаи от "пользовательких" хранимок, которые пишуться на T-SQL. Т.е. эти системные хранимки предоставлены движком сиквела именно для реализации параметризированных запросов, требующих поворного использования планов выполнения.
Re[36]: Кеширование и параметризация запросов
От: Merle Австрия http://rsdn.ru
Дата: 03.12.04 12:59
Оценка:
Здравствуйте, Softwarer, Вы писали:

S>Имхо идеальный вариант — когда драйвер передает на сервер информацию типа

S>
"select .... where a=? and b=?", 1 int,2 int

И чем это отличается от подстановки вызова хранимки перед запросом? Ничем, кроме синтаксиса.

S>Ээ.. следующую цитату plarklin я понял как то, что "параметры, не обернутые в вызов хранимки, не приедут никогда".

Да, все верно, тут я немного прогнал.
На самом деле возможны два варианта вызова.
1. Prepared Queries, осуществляется в несколько этапов. Сначала передается запрос с параметрами (с теми самыми многострадальными вопросиками aka маркерами), сервер подготавливает план, не выполняя запрос и возвращает указатель на подготовленый план. На втором этапе драйвер передает вместе с указателем на план список конкретных значений.
API драйвера делает это через SQLPrepare/SQLExecute и ICommandPrepare интерфейс, API сервера через процедуры sp_prepare/sp_execute
2. Вариант с sp_executesql, здесь все делается за раз, но план в последствии может быть переиспользован, в драйвере это SQLExecDirect, на сервере sp_executesql.

Вообщем, эти хранимки sp_... это просто API сервера для работы с внешними запросами. Видимо были какие-то проблемы добавить методы аналогичные execute для параметризованных запросов, и они реализовали внешний интерфейс этой функциональности через хранимки, но какого-то недостатка я в этом не вижу..
... [ RSDN@Home 1.1.4 revision 0 ]
Мы уже победили, просто это еще не так заметно...
Re[39]: Кеширование и параметризация запросов
От: Softwarer http://softwarer.ru
Дата: 03.12.04 13:01
Оценка:
Здравствуйте, pkarklin, Вы писали:

S>>- Вы говорите, что возможен только вариант с хранимкой

S>>- Merle говорит, что вариант без хранимки возможен, но менее эффективен.

S>>Собственно, меня удивляют оба варианта, но хотелось бы знать "как оно есть на самом деле".


P>Давайте опять разбираться с терминологией. Хранимки реализующие модель prepare\execute ODBC (sp_prepare, sp_execute, sp_uprepare) и хранимка sp_executesql — это системные хранимки. И они на писаны не на T-SQL, в отличаи


С этим не возникает вопросов. Скорее удивляет утверждение, что несистемные хранимки можно писать только на T-SQL (насколько я в курсе, MSSQL поддерживает UDF); что касается Oracle, хранимку можно писать практически на любом языке.

Но я не понимаю — для чего они, эти системные хранимки. Вернее, я могу понять их наличие для реализации, например, динамического SQL, но не очень понимаю, зачем вовлекать какие-то системные хранимки в процесс обработки "обычного SQL".

И все-таки хотелось бы знать: возможен ли вариант "без хранимок" или нет?
Re[37]: Кеширование и параметризация запросов
От: Softwarer http://softwarer.ru
Дата: 03.12.04 13:08
Оценка:
Здравствуйте, Merle, Вы писали:

S>>Имхо идеальный вариант — когда драйвер передает на сервер информацию типа

S>>
"select .... where a=? and b=?", 1 int,2 int

M>И чем это отличается от подстановки вызова хранимки перед запросом? Ничем, кроме синтаксиса.

Отличается отсутствием лишней сущности и свяанных с этим вопросов. Драйверу не нужно делать лишние странные действия, не возникает вопроса "что будет, если я определю собственную хранимку с именем sp_execute" и так далее. Система получается более простой, более замкнутой.

M>Вообщем, эти хранимки sp_... это просто API сервера для работы с внешними запросами. Видимо были какие-то проблемы добавить методы аналогичные execute для параметризованных запросов, и они реализовали внешний интерфейс этой функциональности через хранимки, но какого-то недостатка я в этом не вижу..


Это не то что недостаток, скорее странно. И наводит на мысль, что изначально такой возможности таки не было — в силу чего хранимки и были здорово быстрее — а потом ее добавили "сбоку", так чтобы минимально менять уже реализованное.
Re[36]: Кеширование и параметризация запросов
От: Merle Австрия http://rsdn.ru
Дата: 03.12.04 13:11
Оценка:
Здравствуйте, Softwarer, Вы писали:

S>Это растет из фразы Merle о том, что варианты с приходом "просто sql" и "sp_execute sql" различны по эффективности и сервер в общем случае не может преобразовать менее эффективный вариант в более эффективный.

Это была не совсем правильная фраза..
Там разный подход, немного в одном случа сначала готовится план, клиенту возвращается указатель на этот план, далее клиент вместе с указателем передает список значений и запрос выполняется.
Во втором случае запрос исполняется, параметризованный план остается в памяти, и используется при следующих вызовах.

Просто когда просматривал по диагонали sp_executesql наткнулся на фразу о преимуществах, но не прчитал в каких случаях и почему, ну и выводы сделал соответствующие. .
... [ RSDN@Home 1.1.4 revision 0 ]
Мы уже победили, просто это еще не так заметно...
Re[40]: Кеширование и параметризация запросов
От: pkarklin  
Дата: 03.12.04 13:12
Оценка:
Здравствуйте, Softwarer, Вы писали:

S>С этим не возникает вопросов. Скорее удивляет утверждение, что несистемные хранимки можно писать только на T-SQL (насколько я в курсе, MSSQL поддерживает UDF); что касается Oracle, хранимку можно писать практически на любом языке.


Вот ведь неугомонный Вы наш. Я трактовал в контексте данного топика хранимку, как контейнер для инструкций T-SQL. А так да. Для сиквела есть возможность создания расширенных хранимых процедур, которые могут быть написаны в виде DLL, например, на дельфи, а эти рхп в свою очеред могут быть использованы в UDF. UDF у сиквела могут быть написаны только на T-SQL, имеют кучу ограничений, но могут дергать рхп.

S>Но я не понимаю — для чего они, эти системные хранимки. Вернее, я могу понять их наличие для реализации, например, динамического SQL, но не очень понимаю, зачем вовлекать какие-то системные хранимки в процесс обработки "обычного SQL".


Еще раз. Описанные здесь системные хранимки — единственно возможный вариант для сервера гарантированно повторно использовать план выполнения для ad hoc запросов.

S>И все-таки хотелось бы знать: возможен ли вариант "без хранимок" или нет?


НЕТ.
Re[38]: Кеширование и параметризация запросов
От: Merle Австрия http://rsdn.ru
Дата: 03.12.04 13:22
Оценка:
Здравствуйте, Softwarer, Вы писали:

S>Отличается отсутствием лишней сущности и свяанных с этим вопросов.

Это не лишняя сущность. Для того что бы добиться отклика от сервера нужно вызвать метод его API.
метод может выглядеть как excute( ... ), или как execute(sp_execute ... ) — разницы никакой, поскольку в данном случае sp_execute можно расценивать как часть имени метода.
Сделано было именно так, еще Sybase'ом, видимо для того чтобы иметь возможность получить ту же функциональность и из T-SQL'я.
Переделывать же в дальнейшем более понятным образом это поиметь кучу возни с обратной совместимостью а реальной выгоды — никакой, драйвера и так неплохо этот API понимают, им все равно.

S> Драйверу не нужно делать лишние странные действия,

Никаких лишних действий, просто метод немного странно называется.
... [ RSDN@Home 1.1.4 revision 0 ]
Мы уже победили, просто это еще не так заметно...
Re[38]: Кеширование и параметризация запросов
От: Softwarer http://softwarer.ru
Дата: 03.12.04 13:23
Оценка:
Здравствуйте, Softwarer, Вы писали:

В общем, резюмируя:

В первую очередь, спасибо всем за то, что терпели меня и обстоятельно отвечали. Насколько я понял, сейчас MSSQL в целом одинаково обрабатывает что запросы в пользовательских хранимках, что непосредственно переданные с клиента (используя системные хранимки относительно скрытым от пользователя образом). BDE, работая с MSSQL, по каким-то причинам не пользовалось этим механизмом, поставляя параметры на клиенте.
Re[39]: Кеширование и параметризация запросов
От: wildwind Россия  
Дата: 03.12.04 15:02
Оценка:
Здравствуйте, Softwarer, Вы писали:

S>BDE, работая с MSSQL, по каким-то причинам не пользовалось этим механизмом, поставляя параметры на клиенте.

Думаю, это зависит от того, что находится между BDE и MSSQL: ADO или ODBC или драйвер SQLLinks или еще что.


S>Насколько я понял, сейчас MSSQL в целом одинаково обрабатывает что запросы в пользовательских хранимках, что непосредственно переданные с клиента


Остался неясным (для меня) такой вопрос: в каком случае сервер (MSSQL) может эффективно воспользоваться гистограммами для выбора оптимального плана, и что разработчик может для этого сделать.
Кто может прояснить — плиз.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.