Skip to content

SQL

SQL

Що таке SQL

SQL (Structured Query Language) — це мова для роботи з реляційними базами даних, що використовується для створення, модифікації, управління та отримання даних. Вона є стандартом для більшості сучасних реляційних СУБД, таких як MySQL, PostgreSQL, SQLite та інші.

  • SQL дозволяє створювати структуру бази даних через команди створення таблиць, індексів, та зв’язків між таблицями.
  • Основні операції SQL включають SELECT для вибірки даних, INSERT для додавання, UPDATE для оновлення та DELETE для видалення записів.
  • SQL підтримує складні запити за допомогою умов WHERE, сортування ORDER BY, агрегації даних GROUP BY, а також функцій для роботи з підзапитами та об'єднання таблиць (JOIN).
  • Мова SQL є декларативною, тобто користувач описує, що він хоче отримати або змінити, а не як саме це потрібно зробити.
  • У сучасних застосунках SQL часто використовується через ORM (Object-Relational Mapping) інструменти, такі як SQLAlchemy для Python, що дозволяє взаємодіяти з базою даних через об'єкти класів замість прямого написання SQL-коду.

Приклад базового запиту SQL для вибірки всіх користувачів з бази даних:

SELECT * FROM users WHERE age > 18 ORDER BY name ASC;

Оператори SELECT, INSERT, UPDATE та DELETE

Призначення операторів

  • SELECT для вибірки даних
  • INSERT для додавання записів
  • UPDATE для оновлення записів
  • DELETE для видалення записів

Оператор SELECT використовується для вилучення даних з бази даних. Він дозволяє вибирати певні стовпці з таблиці, фільтрувати дані за умовами, сортувати, групувати і виконувати інші операції над даними.

SELECT column1, column2 FROM table_name WHERE condition;

Оператор INSERT використовується для вставки нових даних у таблицю. Він дозволяє вказувати значення для стовпців або вставляти значення з іншої таблиці.

INSERT INTO table_name (column1, column2) VALUES (value1, value2);

Оператор UPDATE використовується для зміни даних у таблиці. Він дозволяє оновлювати значення стовпців у певних рядках таблиці. Можна вказувати умови для фільтрації даних, які потрібно оновити.

UPDATE table_name SET column1 = value1, column2 = value2 WHERE condition;

Оператор DELETE використовується для видалення даних з таблиці. Він дозволяє видаляти певні рядки таблиці на основі умов.

DELETE FROM table_name WHERE condition

SQL Constraints

Обмеження (Constraints) використовуються для визначення правил для даних у таблиці.

Обмеження використовуються для обмеження типу даних, які можуть входити в таблицю. Це забезпечує точність і достовірність даних у таблиці. Якщо існує будь-який конфлікт між обмеженням і дією з даними, дія переривається.

Обмеження можуть бути на рівні стовпця або таблиці. Обмеження рівня стовпця застосовуються до стовпця, а обмеження рівня таблиці застосовуються до всієї таблиці.

Перелік обмежень

  • NOT NULL - гарантує, що стовпець не може мати значення NULL
  • UNIQUE – гарантує, що всі значення в стовпці відрізняються
  • PRIMARY KEY - комбінація NOT NULL і UNIQUE. Унікально визначає кожен рядок у таблиці
  • FOREIGN KEY - однозначно ідентифікує рядок/запис в іншій таблиці
  • CHECK - гарантує, що всі значення в стовпці задовольняють певну умову

PK - Primary Key, FK -Foreign Key, UNIQUE - Unique constraint

Primary Key (Первинний Ключ) - це унікальний ідентифікатор (стовпець або комбінація стовпців), який визначає конкретний запис в базі даних. Він гарантує унікальність кожного запису в таблиці і дозволяє ефективно виконувати пошук та звертатися до конкретних даних. Кожна таблиця може мати лише один первинний ключ.

CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    username VARCHAR(255)
);

Foreign Key (Зовнішній Ключ) - це поле в таблиці бази даних, яке вказує на Primary Key іншої таблиці. Він встановлює зв'язок між двома таблицями, дозволяючи одній таблиці посилатися на дані в іншій. Це використовується для створення зв'язків між таблицями та забезпечення цілісності даних в базі даних. Таблиця може мати кілька зовнішніх ключів, що вказують на її зв'язок із різними таблицями.

CREATE TABLE orders (
    id SERIAL PRIMARY KEY,
    user_id INT REFERENCES users(id)
);

UNIQUE – обмеження гарантує унікальність значень - всі значення стовпця відрізняються один від одного. Обмеження первинного ключа має автоматичне обмеження на унікальність. В таблиці можна мати багато унікальних обмежень, але тільки одне обмеження первинного ключа таблиці.

CREATE TABLE users (
 id int NOT NULL,
 email varchar(255) UNIQUE, -- all the emails shoud be unique
 CONSTRAINT pk_user PRIMARY KEY (id)
);

Оператор та види JOIN

Оператор JOIN в SQL використовується для об'єднання даних з двох або більше таблиць на основі визначених умов. JOIN дозволяє комбінувати дані з різних таблиць в один результат.

Умова з'єднання вказується в реченні ON. Ця умова визначає, які рядки двох вихідних таблиць вважаються "відповідними" один одному.

Слова INNER та OUTER не є обов'язковими у всіх формах. За замовчуванням передбачається INNER(внутрішнє з'єднання), а при вказанні LEFT, RIGHT і FULL - зовнішнє з'єднання.

Види джойнів

  • JOIN (INNER JOIN)
  • LEFT JOIN (LEFT OUTER JOIN)
  • RIGHT JOIN (RIGHT OUTER JOIN)
  • FULL JOIN (FULL OUTER JOIN)
  • CROSS JOIN

  • INNER JOIN - Повертає ті рядки, які мають відповідні значення в обох таблицях.

SELECT Orders.order_id, Customers.customer_name
FROM Orders
JOIN Customers ON Orders.customer_id = Customers.customer_id;
  • LEFT OUTER JOIN - Повертає всі рядки з лівої (першої) таблиці та відповідні значення з правої (другої) таблиці. Якщо відповідних значень немає, повертається NULL.
SELECT Customers.customer_name, Orders.order_id
FROM Customers
LEFT JOIN Orders ON Customers.customer_id = Orders.customer_id;
  • RIGHT OUTER JOIN - Повертає всі рядки з правої (другої) таблиці та відповідні значення з лівої (першої) таблиці. Якщо відповідних значень немає, повертається NULL. Це з'єднання є протилежним до лівого (LEFT JOIN).
SELECT Customers.customer_name, Orders.order_id 
FROM Customers 
RIGHT JOIN Orders ON Customers.customer_id = Orders.customer_id;
  • FULL OUTER JOIN - Повертає всі рядки з обох таблиць, і якщо відповідних значень немає, повертається NULL. Фактично це одночасний LEFT та RIGHT JOIN.
SELECT Customers.customer_name, Orders.order_id 
FROM Customers 
FULL JOIN Orders ON Customers.customer_id = Orders.customer_id;
  • CROSS JOIN - Повертає декартовий добуток (комбінацію) всіх рядків із першої таблиці та всіх рядків із другої таблиці.
SELECT Customers.customer_name, Products.product_name 
FROM Customers 
CROSS JOIN Products;

Латеральний JOIN, (LATERAL JOIN) дозволяє використовувати результати попереднього запиту як джерело даних для подальших операцій JOIN, що дозволяє створювати більш складні і гнучкі запити.

Основна властивість латерального JOIN полягає в тому, що він дозволяє включати підзапити, які "бачать" дані з рядків, отриманих від зовнішніх таблиць. Це дозволяє використовувати значення з поточного рядка як параметр для підзапиту, що в свою чергу дозволяє гнучко маніпулювати даними.

SELECT e.employee_name, t.task_name
FROM employees e
LEFT JOIN LATERAL (
    SELECT task_name
    FROM tasks
    WHERE tasks.employee_id = e.employee_id
    LIMIT 5 -- Limit the number of tasks per employee, for example
) t ON true;

Підзапити

Підзапити SQL - це запити, вкладені всередині інших запитів.

Підзапити можуть бути використані для створення складних і гнучких запитів, які вимагають більш складної логіки або операцій з даними. Підзапити можуть використовуватися в різних частинах SQL-запиту, таких як SELECT, FROM, WHERE, HAVING та інших.

Підзапити можуть бути менш ефективними з точки зору продуктивності, особливо під час роботи з великими обсягами даних. Вони можуть призвести до підвищеного часу виконання запитів та навантаження на базу даних. В таких випадках можна спробувати замінити підзапит на JOIN.

Підзапит в операторі SELECT

SELECT product_name, (SELECT AVG(price) FROM prices WHERE product_id = products.id) as avg_price
FROM products;

Підзапит в операторі FROM

SELECT product_name, price
FROM products
JOIN (SELECT product_id, AVG(price) as avg_price FROM prices GROUP BY product_id) as subquery
ON products.id = subquery.product_id
WHERE price > subquery.avg_price;

Підзапит в операторі WHERE

SELECT order_id, customer_id
FROM orders
WHERE customer_id IN (SELECT customer_id FROM customers WHERE customer_type = 'premium');

Агрегатні функції і GROUP BY

Агрегатні функції SQL використовуються для обчислення агрегатних значень на основі даних в стовпцях таблиці.

Основні агрегатні функції SQL

  • COUNT
  • SUM
  • AVG
  • MIN
  • MAX

COUNT Повертає кількість рядків або значень у стовпці. Може використовуватися з модифікатором DISTINCT для розрахунку унікальних значень.

SELECT COUNT(*) AS total_orders
FROM Orders;

SUM Повертає суму значень у стовпці. Може використовуватись лише з числовими стовпцями.

SELECT SUM(order_total) AS total_sales
FROM Orders;

AVG Повертає середнє значення значень у стовпці. Може використовуватись лише з числовими стовпцями.

SELECT AVG(order_total) AS avg_order_total
FROM Orders;

MIN Повертає мінімальне значення у стовпці. Може використовуватись з будь-яким типом даних.

SELECT MIN(order_date) AS earliest_order_date
FROM Orders;

MAX Повертає максимальне значення у стовпці. Може використовуватись з будь-яким типом даних.

sqlCopy code
SELECT MAX(order_date) AS latest_order_date
FROM Orders;

Оператори GROUP BY, HAVING використовуються спільно з агрегатними функціями для виконання агрегації на рівні груп або для створення зведених звітів.

GROUP BY Використовується для угруповання результатів по одному або декільком стовпцям.

SELECT customer_id, COUNT(*) AS order_count
FROM Orders
GROUP BY customer_id;

HAVING Використовується для фільтрації груп після застосування GROUP BY на основі умов, заданих у HAVING.

SELECT customer_id, COUNT(*) AS order_count
FROM Orders
GROUP BY customer_id
HAVING COUNT(*) > 5;

У чому різниця між операторами HAVING та WHERE?

Оператор HAVING використовується у зв'язці з GROUP BY, щоб фільтрувати рядки на основі агрегатних функцій. У свою чергу оператор WHERE фільтрує рядки перед групуванням. Простіше кажучи WHERE використовується для звуження пошуку на рівні рядків, а HAVING вибирає конкретні результати після групування.

SELECT department, COUNT(*) AS total_employees
FROM employees
GROUP BY department
HAVING total_employees > 10;

UNION та UNION ALL

UNION та UNION ALL використовуються для об’єднання результатів кількох запитів у один набір даних. - UNION видаляє дублікати зі з'єднаного набору результатів. Використовується, коли потрібен унікальний список значень, при цьому виконує додаткову перевірку для усунення дублікатів, що може уповільнити виконання запиту на великих наборах даних. - UNION ALL зберігає всі записи, включаючи дублікати.

Обидва оператори вимагають, щоб кількість і типи стовпців у всіх запитах, що об'єднуються, збігалися.

-- Union example, duplicates will be removed
SELECT column_name FROM table1
UNION
SELECT column_name FROM table2;

-- Union All example, duplicates will be kept
SELECT column_name FROM table1
UNION ALL
SELECT column_name FROM table2;

Функції в SQL

Рядкові функції

  • CONCAT()
    • Об'єднання двох або більше рядків.
    • SELECT CONCAT('Hello', 'World'); -- Результат: 'HelloWorld'
  • LENGTH()
    • Повертає довжину рядка.
    • SELECT LENGTH('Hello'); -- Результат: 5
  • UPPER()
    • Перетворення рядка у верхній регістр.
    • SELECT UPPER('hello'); -- Результат: 'HELLO'
  • LOWER()
    • Перетворення рядка на нижній регістр.
    • SELECT LOWER('WORLD'); -- Результат: 'world'
  • SUBSTRING()
    • Вилучення підрядка з рядка.
    • SELECT SUBSTRING('HelloWorld', 6, 5); -- Результат: 'World'

Математичні функції

  • ABS()
    • Повертає абсолютне значення числа.
    • SELECT ABS(-5);-- Результат: 5
  • ROUND()
    • Округлення числа до заданої кількості знаків після коми.
    • SELECT ROUND (3.14159, 2); -- Результат: 3.14
  • CEILING()
    • Округлення числа у велику сторону до найближчого цілого.
    • SELECT CEILING (3.2); -- Результат: 4
  • FLOOR()
    • Округлення числа в меншу сторону до найближчого цілого.
    • SELECT FLOOR(3.8); -- Результат: 3
  • RAND()
    • Генерація випадкового числа.
    • SELECT RAND(); -- Результат: випадкове число від 0 до 1

Інші функції

  • COALESCE()
    • Повертає перше ненульове значення зі списку значень.
    • SELECT COALESCE(column1, column2, column3, 'N/A') FROM table1;
  • NULLIF()
    • Повертає NULL, якщо два значення дорівнюють.
    • SELECT NULLIF(column1, 0) FROM table1;
  • CASE()
    • Виконує умовну логіку SQL запиту.
    • SELECT column1, CASE WHEN column1 > 0 THEN 'Positive' ELSE 'Negative' END FROM table1;

UPSERT

UPSERT (update or insert) у SQL — це операція, яка дозволяє вставляти нові рядки у таблицю або оновлювати існуючі, якщо такі вже присутні. Це корисно для забезпечення цілісності даних та уникнення дублювання записів. Залежно від бази даних, синтаксис UPSERT може відрізнятися.

  • У PostgreSQL UPSERT реалізується через INSERT ... ON CONFLICT. Ви вказуєте, що робити у разі конфлікту (наприклад, оновити дані).
  • У MySQL використовують INSERT ... ON DUPLICATE KEY UPDATE. Це оновлює рядок, якщо ключ уже існує.
  • У SQLite UPSERT доступний через INSERT ... ON CONFLICT.
  • У Oracle використовують MERGE для реалізації UPSERT-поведінки.

Приклад для PostgreSQL

INSERT INTO users (id, name, email) 
VALUES (1, 'John Doe', 'john.doe@example.com') 
ON CONFLICT (id)  -- identifies the field causing the conflict
DO UPDATE SET 
    name = EXCLUDED.name,
    email = EXCLUDED.email;

-- "EXCLUDED" is a special reference to the data being attempted to be inserted

Цей запит вставить новий запис, якщо id не існує, або оновить name та email, якщо запис із таким id уже присутній.

Що робить SELECT FOR UPDATE?

SELECT FOR UPDATE – це SQL-конструкція, яка використовується для блокування рядків, що вибираються під час виконання запиту, щоб уникнути конкурентних змін даних. Ця конструкція зазвичай застосовується в транзакціях для забезпечення консистентності даних.

Вона виконує ексклюзивне блокування рядків, які відповідають умовам запиту, і дозволяє тільки одному процесу або транзакції читати або змінювати ці рядки. Інші транзакції, що спробують виконати SELECT FOR UPDATE для цих же рядків, будуть чекати, поки поточна транзакція завершиться (коміт або ролбек).

Зазвичай використовується, коли є потреба прочитати дані, провести певні обчислення та потім оновити ці дані без ризику, що інша транзакція зможе змінити їх між читанням і записом. Це важливо для уникнення проблем, таких як race conditions.

Недоліком є те, що використання SELECT FOR UPDATE може призвести до зменшення швидкодії за рахунок блокування ресурсів та можливих deadlock-ів. Тому його треба застосовувати з обережністю в системах з високою конкуренцією запитів.

BEGIN;

-- Selecting rows for update
SELECT * FROM orders
WHERE status = 'pending'
FOR UPDATE;

-- Performing update based on previous select
UPDATE orders
SET status = 'processing'
WHERE status = 'pending';

COMMIT;

Що таке віконні функції і як вони працюють?

Віконні функції - це засіб в SQL, який дозволяє виконувати обчислення на підмножині рядків з результатами запиту і керувати їх порядком та групуванням. Вони корисні для виконання аналізу даних на рівні рядків і дозволяють враховувати взаємозв'язані дані при обчисленнях.

У PostgreSQL можна використовувати віконні функції, використовуючи ключове слово OVER. Наприклад, давайте припустимо, що у нас є таблиця orders зі стовпцями order_date, customer_id і order_amount. Ми можемо використовувати віконну функцію SUM для обчислення кумулятивної суми замовлень для кожного клієнта впродовж часу.

SELECT 
    order_date,
    customer_id,
    order_amount,
    SUM(order_amount) OVER (PARTITION BY customer_id ORDER BY order_date) AS cumulative_order_amount
FROM 
    orders;

У цьому запиті ми використовуємо функцію SUM(order_amount) OVER (PARTITION BY customer_id ORDER BY order_date). Частина PARTITION BY customer_id розділяє дані на групи за customer_id, а ORDER BY order_date визначає порядок сортування за датою замовлення.

Таким чином, для кожного рядка ми отримаємо значення кумулятивної суми суми замовлень для відповідного клієнта на даний момент.

Досягти того ж результату, що і у вище наведеному прикладі, можна використовуючи GROUP BY.

SELECT 
    order_date,
    customer_id,
    order_amount,
    SUM(order_amount) AS cumulative_order_amount
FROM 
    orders
GROUP BY 
    customer_id, order_date, order_amount
ORDER BY 
    customer_id, order_date;

Обидва запити дають однаковий результат - кумулятивну суму сум замовлень для кожного клієнта на основі дати замовлення. Однак, використання віконних функцій дозволяє уникнути необхідності вказувати всі стовпці з запиту в розділі GROUP BY. Використання OVER і PARTITION BY дозволяє більш гнучко визначити, як розподілити дані для обчислень, і отримати більш зрозумілий і компактний код.

В більшості випадків використання віконних функцій є більш ефективним та швидким способом порівняно з використанням GROUP BY, особливо при роботі з великими наборами даних. Віконні функції дозволяють виконувати обчислення на підмножині рядків без потреби створювати окремі групи. Це може призвести до кращої продуктивності, оскільки система управління базами даних може оптимізувати розрахунки в межах віконного фрейму.

При використанні підходу GROUP BY база даних має створювати відмінні групи на основі стовпців групування, що може включати додаткові кроки сортування та агрегації. Цей процес може стати більш витратним з точки зору ресурсів зі збільшенням обсягу даних.

Агрегатні віконні функції ROW_NUMBER, RANK, DENSE_RANK

Агрегатні віконні функції SQL дозволяють агрегувати дані всередині певного вікна або діапазону рядків, визначеного за допомогою віконного виразу. Віконні функції можуть бути корисними для аналізу даних, таких як ранжування, обчислення відмінностей між значеннями, знаходження першого або останнього значення всередині вікна та інших аналітичних операцій.

Віконні функції

  • ROW_NUMBER
  • RANK
  • DENSE_RANK

ROW_NUMBER() Повертає порядковий номер рядка всередині вікна. Нумерація починається з першої.

Наступний запит обирає ідентифікатор, ім'я та оцінку студентів з таблиці "students" та призначає їм порядкові номери всередині вікна, відсортованого за зменшенням оцінок.

SELECT id, name, score, ROW_NUMBER() OVER (ORDER BY score DESC) AS row_num
FROM students

RANK() Повертає ранг (порядковий номер) рядка всередині вікна, пропускаючи дублікати, та пропускаючи наступний порядковий номер у разі, якщо кілька рядків мають одне й те саме значення.

Наступний запит обирає ідентифікатор, ім'я та оцінку студентів з таблиці "students" і призначає їм ранги всередині вікна, відсортованого за спаданням оцінок, пропускаючи дублікати оцінок.

SELECT id, name, score, RANK() OVER (ORDER BY score DESC) AS rank_num
FROM students

DENSE_RANK() Повертає щільний ранг (порядковий номер) рядка всередині вікна, не пропускаючи дублікати, і не пропускаючи наступний порядковий номер у випадку, якщо кілька рядків мають те саме значення.

Наступний запит обирає ідентифікатор, ім'я та оцінку студентів з таблиці "students" та призначає їм щільні ранги всередині вікна, відсортованого за спаданням оцінок, без пропуску дублікатів оцінок.

sqlCopy code
SELECT id, name, score, DENSE_RANK() OVER (ORDER BY score DESC) AS dense_rank_num
FROM students

SQL ін'єкції - що таке, як захиститись?

SQL-ін'єкції — це один із найпоширеніших типів атак на базу даних, коли зловмисник вставляє шкідливий SQL-код у запит, що виконується сервером. Це може призвести до витоку даних, модифікації бази або навіть повного видалення даних.

Основна причина SQL-ін'єкцій — неправильна обробка даних, які надходять від користувача, та їх безпосереднє використання у SQL-запитах. Наслідки атак можуть бути дуже серйозними: викрадення конфіденційної інформації, несанкціоновані зміни даних, створення облікових записів з підвищеними привілеями тощо.

Приклад небезпечного коду

user_input = "1; DROP TABLE users;"  # Malicious input
query = f"SELECT * FROM users WHERE id = {user_input};"
cursor.execute(query)  # This executes malicious SQL code

Методи захисту: - Використання параметризованих запитів або підготовлених виразів (prepared statements). Це дозволяє відокремити дані від SQL-логіки.

user_input = "1; DROP TABLE users;"  # This will now be treated as plain data
query = "SELECT * FROM users WHERE id = %s;"
cursor.execute(query, (user_input,))  # Using parameterized query to prevent SQL injection
  • Застосування ORM (наприклад, Django ORM або SQLAlchemy), яке автоматично обробляє вхідні дані.
user = User.objects.filter(id=user_input).first()  # ORM escapes input automatically
  • Валідація та фільтрація вхідних даних. Обмеження типів даних (наприклад, числові значення).
  • Мінімізація прав користувачів бази даних. Акаунт, через який додаток підключається до бази, повинен мати лише необхідні привілеї.
  • Використання веб-фаєрволів (WAF) для моніторингу та блокування шкідливих запитів.
  • Логування та моніторинг запитів допоможуть вчасно виявити підозрілу активність.

View, Materialised View

У SQL View (представлення) та Materialized View (матеріалізоване представлення) — це способи роботи з даними, що полегшують доступ до складних запитів або великих наборів даних. Вони мають схожість, але виконують різні завдання.

Ключові відмінності

  • View завжди показує актуальні дані, тоді як Materialized View може відображати застарілі дані до моменту рефрешу.
  • View не займає додаткового місця в пам’яті, а Materialized View зберігає результати фізично.
  • Materialized View краще підходить для великих обсягів даних, якщо запит часто повторюється і важливіша швидкість, ніж актуальність.

View

  • View — це віртуальна таблиця, яка базується на результаті SQL-запиту. Дані у View завжди актуальні, оскільки витягуються з базової таблиці під час виконання запиту.
  • View не зберігає дані фізично, а лише визначення запиту.
  • Використовується для спрощення складних запитів, підвищення безпеки (обмеження доступу до певних колонок або рядків) та створення абстракцій над базою даних.
  • Оновлення даних через View можливе, якщо виконуються певні умови (наприклад, відсутність агрегатів у запиті).
CREATE VIEW active_users AS
SELECT id, name, email
FROM users
WHERE is_active = true;

-- Запит до View
SELECT * FROM active_users;

Materialized View

  • Materialized View — це таблиця, яка зберігає результат SQL-запиту фізично. Дані в Materialized View не оновлюються автоматично; потрібно виконувати рефреш для їх оновлення.
  • Використовується для покращення продуктивності, особливо для часто виконуваних складних запитів або агрегатів на великих наборах даних.
  • Рефреш може бути виконаний вручну або автоматично залежно від налаштувань.
  • Materialized View може мати індекси для прискорення запитів.
CREATE MATERIALIZED VIEW monthly_sales AS
SELECT product_id, SUM(sales) AS total_sales
FROM sales
GROUP BY product_id;

REFRESH MATERIALIZED VIEW monthly_sales; -- Refresh Materialized View
SELECT * FROM monthly_sales; -- Query Materialized View

EXPLAIN та EXPLAIN ANALYZE

EXPLAIN - це команда, яка надає інформацію про план виконання запиту. Вона показує, як база даних планує виконати запит, включаючи індекси, порядок виконання операцій та очікувані витрати, що допомагає в оптимізації запитів. Сам запит у разі не виконується.

EXPLAIN ANALYZE виконує пояснюваний вираз, навіть якщо це insert, update або delete.

Приклад використання команди EXPLAIN

EXPLAIN SELECT * FROM employees WHERE age > 30;

Seq Scan on employees (cost=0.00..12.50 rows=3 width=100)
 Filter: (age > 30)

База даних буде виконувати послідовне сканування (Seq Scan) таблиці employees і застосовувати фільтр age > 30. Поле cost показує передбачувані витрати виконання операції термінах часу і ресурсів.

EXPLAIN допомагає виявити потенційні проблеми у запитах, такі як відсутність індексного сканування, що може вказувати на необхідність додавання індексів або переписування запитів для покращення продуктивності.

Використання EXPLAIN особливо корисне при роботі зі складними запитами або великими обсягами даних, оскільки дозволяє заздалегідь зрозуміти, як виконуватиметься запит, і які оптимізації можуть знадобитися.