Обновить
20
Владислав@Akina

Сетевой администратор

1,5
Рейтинг
12
Подписчики
Отправить сообщение

SQLite.. на сервере (Хабы: .. Серверная оптимизация).. в 2026 году.. смешно.

А так-то всё вполне ожидаемо.

Электролиз подходит, в том числе, для очистки морской воды от соли.

По-моему, электролиз как раз очищает морскую воду от ... воды. Именно вода разлагается на составляющие и т.о. удаляется из исходного раствора.

говоря о цене, мы говорим о цене саппорта такого решения, а не о нагрузке на железо.

Сколько вам стОит саппорт любой стандартной функции из любой стандартной библиотеки? думаю, бесплатно. А если она из стандартной для проекта, а то и для всей фирмы, пользовательской библиотеки - что, что-то меняется? стоимость создания - это не саппорт, не учитываем, исправление ошибок, неправильно учтённых краевых, тестирование, отладка, и т.д., и т.п. - это составные части стоимости создания, тоже не саппорт, не учитываем. Так откуда ненулевая цена саппорта за функцию, которая вылизана, отлажена, протестирована, включена в пользовательскую библиотеку, и просто используется, как любая другая стандартная или пользовательская функция?

Да, в этом процессе я не указываю, где нужно использовать LLM, согласен. Но я как-то и изначально не собирался. Да и вообще я не о том говорил, я просто оспорил тезис, что описанная операция не реализуется одним запросом, и, по-моему, привёл корректный контрпример.

вот тут уже учитывается сколько у вас "больших" varchar колонок

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

А ещё в MySQL, в отличие от PostgreSQL, нельзя указать просто VARCHAR, без указания максимального размера помещаемых данных.

база скажет row size limit exceed (даже на пустой таблице, без данных)

Именно поэтому использование xTEXT(size) или xTEXT+CHECK(size) в MySQL предпочтительнее VARCHAR(size) - и оно работает ровно так, как описано в статье.

Индекс — это отдельная структура данных (обычно B-tree), которая хранит отсортированные значения колонки и указатели на строки.

Это НЕ относится к кластерному индексу.

Почему нельзя просто проиндексировать всё?

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

но какой ценой?

Что? Посчитать тупо арифметику на сервере - это, по вашему мнению, цена??? А на самом деле это то, что вы при всём своём желании не сможете зарегистрировать, потому что эта ваша цена будет гораздо ниже точности измерения. Тьфу, и растереть.

3 банальных стейтмента против двойного CTE с намеренной ошибкой-абортом

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

А что, если резервных счетов - два? или три? под каждый вариант напишете свой код, да? А вот на стороне SQL это всё делается опять же одним запросом, даже если этих счетов десяток.

если есть рабочий вариант без локов, который держит конкурентный тест на двух счетах — с интересом изучу

Ну вот, быстренько накидал: fiddle. Оптимальностью не пахнет, даже два CTE избыточны, но принцип демонстрируется. Изменяя cte1.amount, можно убедиться, что все три варианта (достаточно main счёта, достаточно суммарно, недостаточно) обрабатываются правильно.

Текст запроса (на всякий случай)
WITH 
cte1 (main_balance, reserve_balance, amount) AS 
    ( -- получить балансы счетов в одну запись
    SELECT main.balance, 
           reserve.balance,
           100 
    FROM accounts reserve
    CROSS JOIN accounts main
    WHERE reserve.id = 'reserve'
      AND main.id = 'main'
    ),
cte2 (main_balance, reserve_balance) AS 
    ( -- посчитать итоговые суммы
    SELECT GREATEST(main_balance - amount, 0),
           GREATEST(main_balance + reserve_balance - amount - GREATEST(main_balance - amount, 0))
    FROM cte1
    )
UPDATE accounts -- записать итоговые суммы
SET balance = CASE id WHEN 'main'    THEN main_balance
                      WHEN 'reserve' THEN reserve_balance
                      END
FROM cte2
WHERE reserve_balance >= 0
  AND id IN ('main', 'reserve');

Для того, чтобы избежать описанной вами проблемы, достаточно протащить за собой через CTE старые значения и сравнить во внешнем запросе с текущими. Если хотя бы одна запись изменена - спровоцировать не-выполнение запроса или ошибку (последнее - проще, что-нить вроде 1/ifnullif(nullif())).

Подробный разбор: списание с овердрафтом

Что за бред у вас там? Читаем из таблицы accounts, а main и reserve - это значения-параметры, передаваемые в запрос. А вот пишем в таблицы main и reserve.

Почему не атомарный: сколько снять с каждого (70 и 30) вычисляется из балансов обоих счетов — это решение в коде, одной командой balance = balance - X не выразить.

Да, PostgreSQL не умеет многотабличный UPDATE. Зато умеет UPDATE в CTE. Так что всё прекрасно выражается одним запросом. Включая и обеспечение того, что итоговый balance не вылетел в минус в обеих записях - для этого есть функция GREATEST(). И не нужно ничего считать в коде, не требуются ни транзакции, ни FOR UPDATE.

и на 10 было точно так же

Вот уж точно нет. Или вы автозагружали какие-то программы/модули, которые использовали не дефолтный браузер, а напрямую запускали Edge/

Но пока что на маркетплейсах висит плашка "товар имеет недостаток из-за отсутствия RuStore и Max".

А над остальными тогда надо повесить плашку "товар имеет недостаток из-за присутствия RuStore и Max".

Отдельные исправления складываются в единый паттерн — Idempotency Barrier — который одновременно закрывает все четыре режима отказа.

  • Устранено 99,98% инцидентов с дубликатами платежей на 14B+ транзакций в месяц (от пика 342/час до 0,07/час)

То есть один-два дубля в день таки приключаются. А по какому сценарию? Какому-то неописанному пятому? Или всё же закрытие не абсолютно? Или вообще по этому моменту никакой информации нет?

Вот только не говорите мне, что у вас ВСЕ проблемы - только и исключительно из-за багов, что если нет бага - то нет и проблем. Всё равно не поверю.

MySQL закрыл баг из 2005 года

Да с чего вы все решили, что это баг? То, что такое поведение описано в багтраке, не делает его багом. О чём, кстати, явно написано в первом же комментарии: "this is a known problem" (это известная проблема). И такое поведение явно описано в документации (для всех версий, для которых документация доступна на сайте) - то есть это как минимум не бага, а фича. И такое поведение было вполне оправдано - каскадные операции инициировались движком (Engine) таблицы, который вообще не в курсе наличия в структуре внешних ключей, не говоря уж про другие таблицы.

И то, что сделал Оракл, очень трудно назвать закрытием бага. На самом деле реализован альтернативный механизм выполнения каскадных операций - ранее их выполнял движок, а теперь добавлен ещё и механизм их выполнения на уровне SQL. И переключение между этими механизмами выполняется установкой переменных innodb_native_foreign_keys и enable_cascade_triggers (обе - только глобальные и не динамические). То есть теперь доступно как старое (ничего не сломается при обновлении), так и новое поведение. Причём новое поведение не зависит от используемого движка (SQL-уровень абстрагирован от хранения), и нужно будет внимательно тестировать поведение нового механизма при использовании нетранзакционных движков - в этом случае возможны определённые сюрпризы.

Подробности можно посмотреть тут: No More Silent Foreign Key Cascades: MySQL 9.7 Lets Child Triggers Speak Up.

Ничего не посоветую. Изучать ради изучения? можно даже не браться, толку не будет. Цель. Именно она определяет, по каким материалам, в каком порядке и как именно разумнее изучать. Аналитик, DBA, не-SQL программист и SQL-программист - всем им нужны свои материалы, методики и способы изучения, со своими акцентами и откладываниями "на потом".

Фикс

Ну и странный какой-то фикс. Почему мы юзера удаляем мягко, а запись из листа ожидания - жёстко?

У каждого компонента было своё определение «удалённый пользователь». У некоторых его не было вообще.

Ну бардак он и есть бардак.

Здесь код promoteFromWaitlist написан правильно — он делает именно то для чего предназначен: находит первого в очереди без активного appointment и продвигает его.

А если продолжить "... плюя на всё" - то уже как-то возникают сомнения в правильности. Своё сделал, а там хоть трава не расти.

PS. Stored procedures.

Полистал отрывок.. ну, для аналитиков сойдёт. Хотя терминологию от Excel тащить в SQL, не различая хранимые данные и их отображение на листе или экране, как по мне, совсем неправильно.

O_O Что, РКН уже и с той стороны научился блокировать?

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

Ха! да кабы были вы на уровне регистров процессора! Там есть XCHG, совершающая обмен одной командой и не использующая промежуточную переменную (откуда собственно и вылез весь ваш оверхед). Или это уже уровень.. кто у нас там идёт там за сеньором - гуру?

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

Буквы вроде русские, слова тоже, но язык явно не русский..

Находящимся на борту было приказано оставить все свои вещи в самолёте перед высадкой. В итоге их отправили в испанию утренним рейсом.

Их - это пассажиров, или оставленные ими в самолёте вещи?

Читаемость префиксов — DOC-1001 vs абракадабра

Префиксы - читают. То есть видят и знают.

Безопасность через префикс: даже зная ID, не знаешь префикс

Объясните мне, дураку, почему прочитанный и известный префикс - неизвестен?

1
23 ...

Информация

В рейтинге
1 950-й
Откуда
Зеленоград, Москва и Московская обл., Россия
Дата рождения
Зарегистрирован
Активность