Сильно сомневаюсь. Хотя бы потому, что производительность — это объем работы в единицу времени, а стоимость — это оценка общего объема работы. А во-вторых, оценка может слабо коррелировать с реальностью, это характеристики из двух разных вселенных.
В этом примере обновление отработало верно, но запрос SELECT, который выполнялся долго (для демонстрации эффекта в него вставлен pg_sleep), увидел разные состояния таблицы: одна строка - до обновления, вторая - уже после.
Загадочные ~>=~ и ~<~. В документации, в разделе посвященным текстовым операторам, они отсутствуют. Я пытался гуглить, по ним вообще нет никакой информации. Знаю только, что еще существуют операторы ~<=~ и ~>~. И все они работают с текстом таинственным образом.
Там ничего таинственного, эти операторы сравнивают строки посимвольно, без учета правил сортировки (collation). В доке их, действительно, почему-то нет. Они входят в классы операторов *_pattern_ops, про которые мимоходом сказано в https://postgrespro.ru/docs/postgresql/16/indexes-opclass#INDEXES-OPCLASS. Видимо, считается, что этого и достаточно.
С LOCK TABLE можно было и в старом варианте сделать, без заголовочной таблицы. Но раз уж она появилась, то теперь достаточно блокировать в ней одну строку с нашим id. Однопоточная вставка от этого, скорее всего, только пострадает, зато многопоточная может выиграть.
Но в общем да, это я и имел в виду, когда говорил, что разрыв сократится.
Проверочный запрос видит только уже зафиксированные строки. Поэтому если фиксация двух пересекающихся строк происходит плюс-минус одновременно, запросы в обоих триггерах ничего не обнаружат и в итоге будут вставлены обе строки. Хотя одна за другой они бы, конечно, не вставились.
Я использовал ровно приведенный в статье пример. Добавьте pg_sleep(10) и выполните:
в первой транзакции INSERT INTO tmp_test_not_range (Id, ValidFrom, ValidUntil, Code, Amt) VALUES (1, '2024-01-01'::date, '2024-01-03'::date, 10, 10.0);
в пределах 10 секунд во второй транзакции INSERT INTO tmp_test_not_range (Id, ValidFrom, ValidUntil, Code, Amt) VALUES (1, '2024-01-02'::date, '2024-01-04'::date, 10, 10.0);
Самый простой способ — вставьте в функцию PERFORM pg_sleep(10); после SELECT ... INTO и перед проверкой. А затем в двух терминалах вставьте по строке с пересекающимися датами.
Без задержки это тоже прекрасно воспроизводится, когда несколько потоков постоянно пишут в таблицу, но шансы, конечно, намного меньше.
Но триггер-то у вас неправильный, он может пропустить одновременную вставку взаимопересекающихся интервалов. А сделаете правильно — разрыв будет уже не такой драматичный.
Хм, а ведь действительно. Думаю, что на практике в таких случаях все же указывают конкретного коня, хотя формально неоднозначности нет. Тестами такая экзотика не проверялась, конечно.
Вот из википедии, например: «Результат преобразования (выходные данные) называется «хешем», «хеш-кодом», «хеш-суммой»...». Мне кажется логичным добавлять что-то к общему слову хеш (хеш-функция, хеш-код, хеш-таблица и т. п.).
Сильно сомневаюсь. Хотя бы потому, что производительность — это объем работы в единицу времени, а стоимость — это оценка общего объема работы. А во-вторых, оценка может слабо коррелировать с реальностью, это характеристики из двух разных вселенных.
Увы, увы. Микросервисы да паттерны.
СУБД — фундамент любой системы, поэтому: Владимир Комаров, «Путеводитель по базам данных»
В этом примере обновление отработало верно, но запрос SELECT, который выполнялся долго (для демонстрации эффекта в него вставлен pg_sleep), увидел разные состояния таблицы: одна строка - до обновления, вторая - уже после.
Там ничего таинственного, эти операторы сравнивают строки посимвольно, без учета правил сортировки (collation). В доке их, действительно, почему-то нет. Они входят в классы операторов *_pattern_ops, про которые мимоходом сказано в https://postgrespro.ru/docs/postgresql/16/indexes-opclass#INDEXES-OPCLASS. Видимо, считается, что этого и достаточно.
Caps Lock бы починить бы.
Протестую, ваша честь! Можно и без ptrack, в режимах page или delta.
Да, примерно так, но это уже гомеопатия — без тестирования в реальных условиях не поймёшь, что окажется эффективнее.
Есть ещё рекомендательные блокировки, это совсем быстро, но с ними надо аккуратно.
Ммм, сейчас в триггере блокируется вся заголовочная таблица. Можно было с тем же успехом блокировать всю основную таблицу.
С
LOCK TABLEможно было и в старом варианте сделать, без заголовочной таблицы. Но раз уж она появилась, то теперь достаточно блокировать в ней одну строку с нашимid. Однопоточная вставка от этого, скорее всего, только пострадает, зато многопоточная может выиграть.Но в общем да, это я и имел в виду, когда говорил, что разрыв сократится.
Проверочный запрос видит только уже зафиксированные строки. Поэтому если фиксация двух пересекающихся строк происходит плюс-минус одновременно, запросы в обоих триггерах ничего не обнаружат и в итоге будут вставлены обе строки. Хотя одна за другой они бы, конечно, не вставились.
Я использовал ровно приведенный в статье пример. Добавьте
pg_sleep(10)и выполните:в первой транзакции
INSERT INTO tmp_test_not_range (Id, ValidFrom, ValidUntil, Code, Amt) VALUES (1, '2024-01-01'::date, '2024-01-03'::date, 10, 10.0);в пределах 10 секунд во второй транзакции
INSERT INTO tmp_test_not_range (Id, ValidFrom, ValidUntil, Code, Amt) VALUES (1, '2024-01-02'::date, '2024-01-04'::date, 10, 10.0);Самый простой способ — вставьте в функцию
PERFORM pg_sleep(10);послеSELECT ... INTOи перед проверкой. А затем в двух терминалах вставьте по строке с пересекающимися датами.Без задержки это тоже прекрасно воспроизводится, когда несколько потоков постоянно пишут в таблицу, но шансы, конечно, намного меньше.
Ммм, не вижу изменений в тексте статьи, но если вы имеете в виду отложенный constraint trigger, то это ничем не поможет.
GiST работает медленней, чем btree, это факт.
Но триггер-то у вас неправильный, он может пропустить одновременную вставку взаимопересекающихся интервалов. А сделаете правильно — разрыв будет уже не такой драматичный.
Хм, а ведь действительно. Думаю, что на практике в таких случаях все же указывают конкретного коня, хотя формально неоднозначности нет. Тестами такая экзотика не проверялась, конечно.
Ничем, это он и есть (:
Вот из википедии, например: «Результат преобразования (выходные данные) называется «хешем», «хеш-кодом», «хеш-суммой»...». Мне кажется логичным добавлять что-то к общему слову хеш (хеш-функция, хеш-код, хеш-таблица и т. п.).
Вот такой тест не проходит:
Получаются разные результаты.
Первый вариант в десятку! А вот во втором есть ошибка.
Симпатично! И верные 8 баллов из 10 (мы не знаем заранее количество голов).
Хм, а что в заголовке намекает на 1С?