Информация об изменениях

Сообщение Re[86]: The door от 27.07.2018 8:46

Изменено 27.07.2018 9:00 vdimas

Re[86]: The door
Здравствуйте, Sinclair, Вы писали:

V>>Это если бы курсы были на каждый день, но курс на данную дату нужно вычислять по max(change_date) where change_date<=doc_date.

V>>В этом месте начинаются тормоза.
S>ЕМНИП, именно этот случай мы с MarlboroMan обсасывали на этом сайте году эдак в 2004. Уже тогда MS SQL прекрасно справлялся с такими джойнами.

MS SQL справлялся с такими джоинами еще с версии 6.5, т.е. с 96-го года, чем нехило меня удивил.
Бо до этого я наблюдал в других диалектах SQL только джоины по строгому равенству inner, либо outer left/right.
FULL не считается, бо он во многих диалектах получается "сам" и без join.

Собсно, удивило то, что в MS SQL план запроса не зависел от того, использовалась ли для обсуждаемых неординарных соединений конструкция join, или простое where.
Т.е. это уже было дело вкусовщины автора запроса.

Но факт остаётся фактом, такое соединение по групповой операции заметно тяжелее, чем обычный джоин.


S>Вот тут было бы уместно показать определение таблиц, запрос, и его план.


Ничего военного там нет — обычный составной кластерный индекс {код_валюты, дата_изменения_курса}, бо ширина индекса практически равна ширине таблицы.


S>Можно даже без соображений на тему улучшения характеристик запроса (хотя, естественно, client-side join приходит в голову первым).


Часто так и есть.
С т.з. базы запрос де-факто не тяжёлый (вернее, последовательность их не тяжёлая).
Тут используются те прикладные знания, что эти данные неизменяемые, т.е. их можно спокойно посасывать без длиной транзакции на всё время раундтрипа.
Но в целом запрос выполняется пару секунд дольше.
При этом сохраняется высокая степень параллелизма, что архиважно (С) для тупой клиент-серверной архитектуры. ))

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

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

Надеюсь, объяснил не очень сумбурно — каждая строка справочных данных содержит в себе поле version, которое инициализируется при вставке или обновляется при обновлении данных. Т.е. ответная часть логики поддержки клиентского кеша реализована на серваке. поле версии относительно узкое (16 бит), при переполнении поля версии (переходу через 0), поля всех строк версий у справочника сбрасываются, а клиент, обнаружив номер версии, меньшей чем у себя, тоже сбрасывает кеш этого справочника. За 3 года эксплуатации только справочник товаров сделал оборот версии через 0. ))

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

Но без всех этих ухищрений с дефолтным быстродействием 3-5 запросов на одноядерном Пентиум-500 МГц оно просто не жило от слова совсем. ))

Понятно, что уже с середины 2000-х годов быстродействия техники стало хватать для разработки "как по учебнику", но если опять потребуется прыгнуть выше головы даже современной техники — то уже понятно что делать.
Re[86]: The door
Здравствуйте, Sinclair, Вы писали:

V>>Это если бы курсы были на каждый день, но курс на данную дату нужно вычислять по max(change_date) where change_date<=doc_date.

V>>В этом месте начинаются тормоза.
S>ЕМНИП, именно этот случай мы с MarlboroMan обсасывали на этом сайте году эдак в 2004. Уже тогда MS SQL прекрасно справлялся с такими джойнами.

MS SQL справлялся с такими джоинами еще с версии 6.5, т.е. с 96-го года, чем нехило меня удивил.
Бо до этого я наблюдал в других диалектах SQL только джоины по строгому равенству inner, либо outer left/right.
FULL не считается, бо он во многих диалектах получается "сам" и без join.

Собсно, удивило то, что в MS SQL план запроса не зависел от того, использовалась ли для обсуждаемых неординарных соединений конструкция join, или простое where.
Т.е. это уже было дело вкусовщины автора запроса.

Но факт остаётся фактом, такое соединение по групповой операции заметно тяжелее, чем обычный джоин.


S>Вот тут было бы уместно показать определение таблиц, запрос, и его план.


Ничего военного там нет — обычный составной кластерный индекс {код_валюты, дата_изменения_курса}, бо ширина индекса практически равна ширине таблицы.


S>Можно даже без соображений на тему улучшения характеристик запроса (хотя, естественно, client-side join приходит в голову первым).


Часто так и есть.
С т.з. базы запрос де-факто не тяжёлый (вернее, последовательность их не тяжёлая).
Тут используются те прикладные знания, что эти данные неизменяемые, т.е. их можно спокойно посасывать без длиной транзакции на всё время раундтрипа.
Но в целом запрос выполняется пару секунд дольше.
При этом сохраняется высокая степень параллелизма, что архиважно (С) для тупой клиент-серверной архитектуры. ))

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

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

Надеюсь, объяснил не очень сумбурно — каждая строка справочных данных содержит в себе поле version, которое инициализируется при вставке или обновляется при обновлении данных. Т.е. ответная часть логики поддержки клиентского кеша реализована на серваке. поле версии относительно узкое (16 бит), при переполнении поля версии (переходу через 0), поля всех строк версий у справочника сбрасываются, а клиент, обнаружив номер версии, меньшей чем у себя, тоже сбрасывает кеш этого справочника. За 3 года эксплуатации только справочник товаров сделал оборот версии через 0. ))

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

Но без всех этих ухищрений с дефолтным быстродействием 3-5 запросов/сек на одноядерном Пентиум-500 МГц оно просто не жило от слова совсем. ))

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