Авторский канал про Базы Данных и SQL
Ресурсы, гайды, задачи, шпаргалки.
Информация ежедневно пополняется!
Cотрудничество: @energy_c
РКН: https://clck.ru/3QREBc
Post #1562
2.34K

- 😁 26
- ❤ 11
- 👍 5
- 🔥 1
SQ @sql_ready
Showing posts older than #1564 · Back to latest

OFFSET…LIMIT прост, но плохо масштабируется: чем дальше страница, тем медленнее запрос и выше риск дубликатов при вставках.Keyset использует курсор (id/дату) и даёт стабильную скорость на больших объёмах.CREATE TABLE posts (
id BIGSERIAL PRIMARY KEY,
title TEXT NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CTE:WITH cursor AS (
SELECT 1000::BIGINT AS last_seen_id
)
OFFSET по keyset-подходу:SELECT p.id, p.title, p.created_at
FROM posts p
JOIN cursor c ON TRUE
WHERE p.id < c.last_seen_id
ORDER BY p.id DESC
LIMIT 20;
id < last_seen_id.last_seen_id для следующего запроса.





• Определим моменты, когда начинается новая сессия;
• Присвоим каждому событию уникальный session_id с помощью оконной суммы;
• Получим полноценные сессии так же, как это делают продуктовые аналитические платформы.

• Разберёте реальные ошибки при развёртывании СУБД;
• Узнаете, как повысить производительность запросов через правильное партицирование и не только;
• Поймёте, как организовать конкурентный доступ и обновления данных без блокировок и простоев;
• Получите шесть конкретных лайфхаков, которые помогут избежать критических проблем.🔊 Продолжайте читать на Habr!
regexp_match и regexp_replace, позволяющие делать это напрямую в SQL.CREATE TABLE users (
id INT,
email TEXT,
profile_code TEXT
);
SELECT
id,
email,
(regexp_match(email, '@(.+)$'))[1] AS domain
FROM users;
regexp_match возвращает один массив, и [1] достаёт первую группу. Паттерн @(.+)$ берёт всё, что стоит после символа @.USR-2391-A":SELECT
id,
profile_code,
(regexp_match(profile_code, '([0-9]+)'))[1] AS numeric_part
FROM users;
([0-9]+) извлекает последовательность цифр.SELECT
id,
regexp_replace(profile_code, '[^A-Za-z0-9]', '', 'g') AS cleaned
FROM users;

PostgreSQL не знает, насколько селективное значение в колонке.ANALYZE users (status);
Index Scan.ALTER TABLE users
ALTER COLUMN status SET STATISTICS 500;

SELECT с результатами второго SELECT из подзапроса, что может быть удобно в некоторых случаях: если подзапрос возвращает небольшое количество строк или когда нужно сравнить значение хотя бы с одним значением из подзапроса.Discount:SELECT product, price
FROM products
WHERE price > ALL (SELECT price FROM products WHERE category = 'Discount');
SELECT DISTINCT customer_id
FROM orders
WHERE product_id = ANY (SELECT product_id FROM products WHERE price > 1000);
SELECT DISTINCT customer_id
FROM orders
WHERE product_id = ANY (SELECT product_id FROM products WHERE category = 'Electronics');
ALL и ANY возможно только с подзапросами и может быть неэффективным, если подзапрос возвращает большое количество строк.





UX определяется не средним временем ответа, а редкими хвостовыми задержками, из-за которых важны именно p95 и p99.• Посчитаем ключевые перцентильные метрики (p50/p95/p99) по каждому маршруту;
• Определим, какие запросы регулярно превышают собственный p99;
• Увидим, какие эндпоинты “убивают” отклик сервиса под нагрузкой;
API и контролировать качество работы системы.