Очень удобная система. Как можно не париться и с помощью импорта тегов перенести переменные с ПЛК в панель.Интересно, а с ОВЕН ПЛК прокатит такой номер?Дизайн делали максимально простой. Понятный. Может где-то кривовато, но всех устроило (заказчика тоже).
Приветствую всех! В прошлый раз я уже рассказывал, как устроен и как работает современный карточный таксофон и какими методами защиты он обладает.
Но оставался ещё один блок, который я тогда так и не упомянул. К моему удивлению, в интернете не так много информации по тому, как он устроен и как работает. Именно о нём мы сейчас и поговорим, а заодно и узнаем, как и от чего он вообще защищает.
❯ Суть такова
В прошлый раз я рассказывал про методы защиты самого аппарата.
Любой современный таксофон оснащён целым рядом конструктивных решений, позволяющих предотвратить его повреждение вандалами или использование злоумышленниками — от банальных концевиков до датчика использования эмулятора и (в совсем продвинутых моделях) контроля фронтов сигналов и тока потребления карты. Многие карты и вовсе имели криптографическую защиту. Таким образом, можно сказать, что без серьёзной подготовки взломать типичный карточный аппарат было невозможно.
Но если нельзя обмануть сам аппарат, то что насчёт чего-то другого? Каждый таксофон подключается самой обычной (на самом деле всё же с некоторыми особенностями, например, на такой линии не работает АОН, но сейчас не об этом) телефонной линией, к которой можно подключиться трубкой монтажника или обычным принесённым с собой городским телефоном.
Например, таким. Если таксофон стоит где-то в помещении, то всё становится ещё проще — достаточно незаметно провести где-то пару проводов, и всё. Именно такие случаи и должна предотвращать аппаратура защиты таксофона.
❯ Что такое АЗТ?
На удивление, в интернете о том, как устроена и работает АЗТ, нет практически никакой информации.
Поиск тоже не даёт ничего интересного, только устройства защиты линии от импульсных перенапряжений (такая плата встроена в сам таксофон) или оборудование для обеспечения конфиденциальности переговоров (тоже довольно интересные железки, но о них не в этот раз).
Но кое-что об АЗТ всё же известно. Представляет она собой некое устройство, подключенное в разрыв между таксофоном и АТС. Если вдруг помимо таксофона появится какое-то другое оборудование или пропадёт связь с самим аппаратом, этот блок должен будет заблокировать линию и (опционально) набрать аварийный номер.
❯ Обзор оборудования
Ну а пока что взглянем на доставшийся нам блок.
Выглядит он как вот такая лёгкая пластмассовая чёрная коробочка.
На обратной стороне название устройства и логотип производителя.
В интернете по запросу «АЗТ-1» ищется немало ссылок, однако полезного нет вообще ничего: только упоминания того, что некоторые модели таксофонов совместимы с данным устройством, да всякий мусор по типу результатов торгов.
Производитель этого устройства легко ищется: это пермские «Интеллектуальные системы и технологии» (ИСТ). Компания эта как раз специализируется на выпуске подобного оборудования связи. Именно ими выпускаются GSM-таксофон ИСТ-001 и линейный ИСТ-002. Впрочем, про блок АЗТ-1 на сайте ни слова. Web Archive тоже ничего не показал.
❯ Внутренности
Откроем крышку.
Внутри единственная плата. На ней два клеммника для подключения линии (слева провода от таксофона, справа от АТС), держатель батарейки CR2032, микроконтроллер, немного дискретных компонентов. Для защиты линии видны два разрядника, два варистора и один самовосстанавливающийся предохранитель.
Наклейка на крышке.
На обратной стороне платы ничего интересного, только надпись IST и какой-то номер.
❯ CMX631AP
Остановимся поподробнее на двух микросхемах.
Первый чип — простенький микроконтроллер PIC12F635 (прошивка которого, увы, залочена). А вот второй заслуживает несколько более подробного рассмотрения. Это детектор сигналов частотой 12/16 кГц в телефонной линии.
Вот его блок-схема.
В плане работы с ним всё тоже очень просто: на одном из выходов появляется низкий уровень каждый раз, когда чип видит частотный сигнал, на другом — когда этот сигнал длится дольше 40 мс.
❯ Про режимы тарификации
Что же это за сигналы? Чтобы это выяснить, для начала необходимо разобраться, как именно производится оплата совершённого звонка. Как известно, единицы с карты списываются в зависимости от длительности разговора. Именно поэтому каждый таксофон является средством измерения и подлежит поверке.
Для этого даже существует специальный прибор, подключающийся вместо считывателя карт к плате таксофона или к считывателю карт через специальный адаптер (тот единственный случай, когда вставка чего-то отличного от карты предусмотрена производителем).
Так вот. Помимо автономной тарификации (когда таксофон сам измеряет тарифные интервалы) существует ещё и централизованная, при которой аппарат списывает баланс с карты не по внутреннему таймеру, а по команде от АТС. У такой системы существовало два варианта.
Первый вариант — списание при смене полярности линии.
Именно такое решение применялось в старых междугородних таксофонах. В монетоприёмник складывались деньги, после чего в процессе разговора при переполюсовке линии срабатывал электромагнит, открывающий шторку монетоприёмника, и очередной пятнадчик проваливался в копилку. Поскольку время разговора в разные города стоило по-разному, за заглатывание денег отвечала именно АТС. Также такая система существовала и во всем известных аппаратах АМТ-69, правда, там такой сигнал был фиксированным — после ответа абонента и каждые три минуты.
Второй вариант — списание при получении специальных тарифных сигналов. Проще говоря, отправляемых АТС в линию тоновых сигналов частотой 16 кГц. Тех самых сигналов, для распознавания которых предназначен чип внутри коробочки.
Устанавливаются все эти режимы в меню.
❯ Как же всё-такие работает АЗТ?
Теперь, когда мы выяснили, что это за сигналы и зачем нужен специальный чип для детектирования, кажется, что всё довольно просто. Коробочка контролирует наличие в линии этих сигналов, а если их не обнаруживается, то блокирует линию и набирает аварийный номер. Но на самом деле всё не так. В одном из разделов РЭ таксофона можно обнаружить примерно следующее:
Всё дело в том, что при работе таксофона в паре с АЗТ сигналы частотой 16 кГц посылает не АТС, а таксофон. Именно по их наличию коробочка определяет, что таксофон исправен, а к линии не подключено ничего лишнего. Если же трубка оказалась снята, а сигналов нет, то блок считает, что к линии подключено что-то не то, и обрывает связь.
Существовали также вот такие блоки, устанавливающиеся непосредственно на кроссе АТС. Впрочем, принцип их действия идентичен.
❯ Про связь с СДУКТ
Как сказано в многочисленных источниках, АЗТ должна совершить звонок по аварийному номеру при обнаружении попытки подключения к линии. Как именно это должно происходить, мне неведомо: никакой документации на это устройство нет. Скорее всего, коробочка просто звонит импульсным набором на этот номер, а аппаратура на АТС регистрирует лишь сам факт вызова, без всякого обмена данных.
Никаких внешних интерфейсов для программирования данных у коробочки нет, так что предположу, что номер записывался путём извлечения чипа из панельки, записи туда нового дампа программатором и установки его обратно. Впрочем, в моём случае в EEPROM ничего не оказалось. Вероятнее всего, судя по состоянию, моя коробочка новая и в неё никогда ничего не записывалось.
❯ Что же в итоге?
Вот такой интересной штукой оказалось это устройство. Используются такие сейчас или нет, мне неведомо. Большая часть таксофонов работает по GSM или радиомосту, а к линейным, если они ещё где-то и сохранились, подключаться уже попросту не имеет смысла: всё равно звонки по ним сейчас бесплатные по всей стране.
Нейросеть видит паттерны, но не чувствует боль базы данных.
Аннотация
В статье проводится сравнительный анализ эффективности использования оператора JOIN и коррелированного подзапроса в СУБД PostgreSQL в условиях высокой параллельной нагрузки. На основе экспериментальных данных опровергаются универсальные рекомендации систем искусственного интеллекта и выявляются ключевые факторы, влияющие на производительность.
ℹ️ Новый инструмент с открытым исходным кодом для статистического анализа, нагрузочного тестирования и построения отчетов доступен в репозитории GitFlic и GitHub
Рассматривается вопрос выбора оптимального паттерна для выполнения запросов при высокой параллельной нагрузке на СУБД: использование JOIN или коррелированного подзапроса.
Были получены рекомендации от нейросетевых моделей:
«Ask Postgres»: Для нагрузочных тестов с растущей параллельностью всегда используйте версию с JOIN. Коррелированные подзапросы с агрегациями — плохая практика в сценариях с высокой конкуренцией.
«DeepSeek»: Для данного сценария производительность будет выше при использовании запроса с LEFT JOIN и GROUP BY.
-> Bitmap Heap Scan on orders o (cost=1.56..7.06 rows=40 width=4) (actual time=0.007..0.017 rows=40 loops=25)
Recheck Cond: (customer_id = c.customer_id)
Heap Blocks: exact=125
-> Bitmap Index Scan on idx_orders_customer_id (cost=0.00..1.55 rows=40 width=0) (actual time=0.004..0.004 rows=40 loops=25)
Index Cond: (customer_id = c.customer_id)
Planning Time: 0.145 ms
Execution Time: 0.718 ms
2.3. Сравнение производительности СУБД в ходе нагрузочного тестирования
В ходе сравнительного нагрузочного тестирования была измерена операционная скорость СУБД при использовании оператора JOIN и коррелированного подзапроса. Согласно результатам, среднее снижение операционной скорости при использовании JOIN составило 288% по сравнению с коррелированным подзапросом.
График изменения операционной скорости в ходе нагрузочного тестирования.
3. Анализ причин некорректности рекомендаций нейросетей
3.1. Применение статических эвристик вместо анализа плана выполнения
Нейросети опираются на общие рекомендации, такие как:
«JOIN обычно эффективнее подзапросов»;
«Избегайте N+1 запросов»;
«Коррелированные подзапросы плохо масштабируются».
Однако они не анализируют конкретные планы выполнения запросов в условиях высокой нагрузки и конкуренции за ресурсы.
3.2. Игнорирование паттернов доступа к данным
Анализ планов выполнения показал:
Запрос 1 (JOIN): Seq Scan on orders (полное сканирование таблицы).
Запрос 2 (Подзапрос): Bitmap Index Scan on idx_orders_customer_id (точечный доступ по индексу).
При параллельных соединениях:
Количество сессий × Seq Scan = количество полных сканирований таблицы orders.
Количество сессий × Index Scan = равномерно распределенная нагрузка на чтение.
3.3. Неучёт механизмов блокировки и конфликтов ресурсов
Проблема JOIN при высокой конкуренции: Все сессии одновременно читают одни и те же страницы таблицы orders, что вызывает конфликт ресурсов (contention) на буферный кэш и подсистему ввода-вывода.
Преимущество подзапроса: Каждая сессия работает с разными частями индекса, что снижает конкуренцию за блокировки и улучшает параллелизм.
3.4. Разный профиль использования памяти
JOIN: Memory Usage: 40 kB + хэш-таблица.
Подзапрос: Точечное использование памяти для каждого клиента.
При множественных сессиях JOIN создает значительную нагрузку на shared_buffers.
4. Критические факторы, упускаемые нейросетями
Влияние на shared_buffers: Множественные последовательные сканирования вытесняют полезные данные из кэша.
Lock contention: Конкуренция за одни и те же ресурсы (блокировки).
Распределение операций ввода-вывода: Индексные чтения лучше распределены.
Параметры PostgreSQL: Значения work_mem, shared_buffers, random_page_cost и других настроек существенно влияют на результат.
5. Причины ошибок в рекомендациях нейросетевых моделей
Нейросети обучаются на синтетических или упрощённых данных, для которых характерны:
Небольшой объём наборов данных (TPC-H, TPC-DS).
Низкая параллельность запросов (1–10 соединений).
Идеализированные индексы.
Отсутствие блокировок и конкуренции за ресурсы (ЦП, ввод-вывод).
В результате модель вырабатывает универсальное правило «JOIN всегда лучше», которое не работает в реальных условиях высокой конкуренции.
6. Заключение
Рекомендации, сгенерированные нейросетями, основаны на общих эвристиках и не могут учитывать всех особенностей конкретной эксплуатационной среды. Они не заменяют глубокого анализа планов выполнения запросов и понимания архитектуры СУБД под нагрузкой. Проведенный эксперимент наглядно демонстрирует важность практического тестирования и невозможность слепого следования автоматизированным советам.
СУБД оказалась прочнее, чем кажется: почему выбор запроса может не иметь значения для общей производительности системы.
ℹ️ Новый инструмент с открытым исходным кодом для статистического анализа, нагрузочного тестирования и построения отчетов доступен в репозитории GitFlic и GitHub
Принято считать, что выбор между JOIN и коррелированным подзапросом — одна из ключевых задач оптимизации, способная кардинально повлиять на нагрузку базы данных. В качестве эксперимента, было проведено нагрузочное тестирование, используя Демобазу 2.0 в качестве полигона и vmstat для мониторинга изменений со стороны инфраструктуры, готовясь наглядно продемонстрировать превосходство одного подхода над другим.
Однако результаты оказались неожиданными. Исследование показало практическое отсутствие существенного влияния выбранной структуры запроса на общую производительность СУБД и сервера. В данной статье показано, что в контексте современной оптимизации запросов и мощного аппаратного обеспечения, "страшилка" о катастрофических последствиях использования коррелированных подзапросов часто преувеличена. Нагрузочное тестирование выявило, что СУБД успешно справляется с обоими типами запросов, а реальное влияние на метрики vmstat оказалось малым, что позволяет разработчикам в подобных случаях делать выбор, основываясь на читаемости кода, а не на гипотетических рисках для производительности.
JOIN bookings.routes r ON r.route_no = f.route_no AND r.validity @> f.scheduled_departure
JOIN (
SELECT
flight_id,
fare_conditions,
COUNT(*) AS seats_booked
FROM bookings.segments
GROUP BY flight_id, fare_conditions
) sb ON sb.flight_id = f.flight_id
WHERE sb.seats_booked > (
SELECT sa.seats_total
FROM seats_agg sa
WHERE sa.airplane_code = r.airplane_code
AND sa.fare_conditions = sb.fare_conditions
)
) overbooked;
Анализ результатов нагрузочного тестирования - производительность СУБД
Операционная скорость СУБД
График изменения операционной скорости СУБД для нагрузочного тестирования с использованием Join и Коррелированного подзапроса.
График изменения относительной разницы операционной скорости для нагрузочного тестирования с использованием коррелированного подзапроса по сравнению с использованием JOIN.
Средняя разница операционной скорости СУБД при использовании JOIN и Коррелированного подзапроса составила 0.58%.
Вывод по результатам анализа метрик производительности СУБД
Использование для тестового запроса JOIN или Коррелированного подзапроса - не оказывает влияния на производительность СУБД в целом и тестового сценария в частности.
Всем привет! Хочу познакомить вас с нашим новым сотрудником. Нет, это не стажёр-энтузиаст, который работает за еду. Это робот Грин от Сбера.
Робот Грин от Сбер
Да, да, тот самый, что работает на базе их GigaChat. И пока все ждут Скайнет, наши ребята тихо и планомерно делают будущее, в котором робот принесёт тебе пиво. Ну, или документы в офисе. Пока что.
Что это за зверь такой?
Представьте себе: человекоподобный робот, который умеет не только болтать с вами на любые темы (спасибо GigaChat), но и ходить, брать предметы и, внимание, находить и исправлять свои же косяки. То есть он такой: «Ой, кажется, я тут накосячил. Ща сам всё исправлю». Мечта любого руководителя, да?
Оснастили его по последнему слову техники: 10 сенсоров для зрения, куча датчиков для равновесия и точных движений. В общем, собрали как швейцарские часы. Только большие и умные.
А что с конкурентами?
Тут самое сочное. В ноябре этого года «Новая технологическая коалиция» (тут вам и Промобот, и Айдол, и другие) с помпой представила своего антропоморфного робота Aidol.
И что вы думаете? Во время презентации он взял и... упал. Прямо на сцене. Классика жанра. Такое чувство, что у нас в стране негласное соревнование: кто соберёт более устойчивого робота. подробно про это было рассказано тут и тут
На этом фоне Грин от Сбера смотрится особенно уверенно. Он скромно молчит о своих технических деталях, зато демонстративно не падает. Уже победа.
Зачем он нужен?
Сбер говорит, что в ближайшее время запустит пилотные проекты по внедрению Грина в разные бизнес процессы. То есть скоро он может появиться в какой-нибудь крупной компании, чтобы помогать с логистикой, работать с клиентами или просто круто выглядеть в углу офиса, поднимая корпоративный дух.
Робот Грин Сбер
Сбер робот гига чат
А вы как думаете? Готовы ли вы работать бок о бок с таким железным коллегой? И главное, кому будете жаловаться, если он накосячит? Его же начальнику, другому такому же роботу?
Напишите в комментах, куда бы вы с удовольствием «трудоустроили» такого робота. Я бы например, доверил ему дома посуду помыть...
LLM могут написать запрос, но не несут ответственности за его выполнение в 50 параллельных сессий.
Производительность СУБД — это не только одиночные запросы, но и их поведение в условиях высокой конкуренции за ресурсы. Нейросети, не обладая контекстом реальной нагрузки, часто предлагают решения, которые выглядят логично в вакууме, но приводят к катастрофическим последствиям при масштабировании. История о двух запросах — прямое тому доказательство.
ℹ️Новый инструмент с открытым исходным кодом для статистического анализа, нагрузочного тестирования и построения отчетов доступен в репозитории GitFlic и GitHub
FOREIGN KEY (customer_id) REFERENCES customers(customer_id) ON DELETE CASCADE );
INSERT INTO orders (customer_id) WITH RECURSIVE data_rows (n) AS ( SELECT 1 UNION ALL SELECT n + 1 FROM data_rows WHERE n < 1000 ) SELECT FLOOR(RANDOM() * 25) + 1 FROM data_rows;
-- Create index on orders table
CREATE INDEX idx_orders_customer_id ON orders (customer_id);".
Тестовый запрос-1
"SELECT c.customer_id, COUNT(o.order_id) AS orders_count INTO test_rec FROM customers c LEFT JOIN orders o ON c.customer_id = o.customer_id GROUP BY c.customer_id;" .
Тестовый запрос-2
"SELECT c.customer_id, (SELECT COUNT(o.order_id) FROM orders o WHERE o.customer_id = c.customer_id) AS orders_count INTO test_rec FROM customers c;" . Тестовая СУБД :
CPU = 8 , RAM = 8GB , Версия PostgreSQL 17.
Нагрузка растет экспоненциально от 10 до 45 одновременных сессий, длительность тестовой итерации 10 минут.
Вопрос - для какого тестового запроса производительность СУБД будет выше в ходе нагрузочного тестирования - при использовании тестового запроса-1 или при использовании тестового запроса-2 ?
1️⃣Ответ нейросети "Ask Postgres"
✅ Производительность будет выше при использовании тестового запроса-1 (LEFT JOIN + GROUP BY)
Обоснование
1. Запрос-1 (JOIN + GROUP BY) — оптимальный
Один проход по таблице orders с использованием индекса idx_orders_customer_id.
PostgreSQL 17 эффективно использует параллельные планы для JOIN и GROUP BY — при 45 сессиях нагрузка распределяется между ядрами CPU.
Минимальная конкуренция за ресурсы: индекс сканируется один раз на запрос, а не 25 раз.
Оптимизатор может применить Hash Join или Merge Join, что особенно эффективно при наличии индекса и небольшом количестве клиентов (25).
Масштабируемость: при росте числа сессий производительность падает умеренно — линейно с числом запросов, а не с числом строк в orders.
Документация подтверждает:
«Subqueries can be transformed into semi-joins» — но только для некоррелир
ованных.
Коррелированные подзапросы (как в запросе-2) не преобразуются в JOIN автом
атически, особенно при использовании COUNT() — это ограничение оптимизатора.
2. Запрос-2 (коррелированный подзапрос) — неэффективный при нагрузке
Для каждой из 25 строк customers выполняется отдельный подзапрос.
При 45 сессиях — 1125 отдельных сканов индекса idx_orders_customer_id в секунду.
Это вызывает: Конкуренцию за блоки индекса → локальные блокировки.
Высокую нагрузку на CPU → много контекстных переключений.
Ограничение параллелизма — подзапросы выполняются последовательно внутри одного запроса.
📌 Рекомендация
Для нагрузочных тестов с растущей параллельностью всегда используйте JOIN-версию (запрос-1).
Коррелированные подзапросы с агрегациями — плохая практика в сценариях с высокой конкуренцией, даже если они выглядят «проще».
Дополнительно: Для ещё большей производительности можно добавить CLUSTER на orders по customer_id, или использовать materialized view для кэширования агрегированных данных, если данные не меняются часто.
✅ Итог: Запрос-1 (LEFT JOIN + GROUP BY) обеспечивает значительно более высокую производительность при нагрузке 10–45 сессий.
2️⃣Ответ нейросети "DeepSeek"
Для данного сценария нагрузочного тестирования производительность будет выше при использовании тестового запроса-1 (с LEFT JOIN и GROUP BY). Обоснование:
Оптимизация выполнения запроса:
Запрос-1 выполняется как одиночный оператор с хеш-соединением и агрегацией, что эффективно обрабатывается планировщиком PostgreSQL.
Запрос-2 использует коррелированный подзапрос, который выполняет 25 отдельных запросов COUNT (по одному на каждого клиента). При параллельных сессиях это создает дополнительную нагрузку.
Эффективность при параллелизме:
Запрос-1 лучше масштабируется благодаря хеш-агрегации и однократному сканированию таблиц.
Запрос-2 генерирует множество индексных сканиваний (используя idx_orders_customer_id), что при 45 сессиях приводит к конкуренции за ресурсы ( latch-конфликты в кэше индексов).
Статистика ресурсов:
При 1000 заказах и 25 клиентах разница незначительна, но при экспоненциальном росте сессий запрос-2 сильнее нагружает CPU (многократные поиски в индексе) и RAM (больше служебных структур на сессию).
Особенности PostgreSQL:
Оптимизатор PostgreSQL эффективнее обрабатывает JOIN-агрегацию, чем вложенные подзапросы, при параллельных выполнениях. Версия 17 дополнительно улучшает параллельные хеш-соединения.
Рекомендация: Для рабочих нагрузок с высоким параллелизмом предпочтительнее использовать запрос-1.