Остались вопросы?
Мы с удовольствием вам поможем
Спасибо! Ваша заявка принята.
Ваша заявка принята. Наш менеджер скоро с вами свяжется
Заказать звонок
Спасибо! Ваша заявка принята.
Спасибо за обращение.
Мы обязательно свяжемся с вами

Время работы офиса
Пн-Пт: 8:00 — 18:00
Сб: 10:00 — 16:00
Вс: выходной

Распространенные ошибки в SQL-запросах и их последствия

Никита Лебедь
28.10.2024
10 мин. читать

Качество кода в запросах к базам данных влияет на работу всей IT-системы и онлайн-проектов. Неправильное использование команд и ошибки в их написании могут привести к потере данных, принятию неправильных бизнес-решений и повышению нагрузки на IT-инфраструктуру.


Чем опасны ошибки в SQL-запросах?

Некорректные запросы к базам данных влекут риски для всей IT-системы.

  • Потеря данных. Ошибки при выполнении определенных команд могут привести к утрате данных. Не забывайте о бэкапах!
  • Искажение данных. Неправильная логика работы с SQL приводит к получению некорректных данных. Это нарушает интеграцию систем, взаимодействие сотрудников и отделов компании. В результате могут приниматься некорректные решения.
  • Снижение производительности. Некорректные запросы могут замедлять работу БД, оказывать дополнительную нагрузку на серверы и негативно влиять на скорость работы всей системы.
  • Сложности исправлений. Одни ошибки трудно отследить, а другие потребуют дополнительных расходов на исправление.
  • Репутационные издержки. Ошибки в работе с запросами и базами данных могут негативно повлиять на доступность всего онлайн-проекта и привести к падению репутации компании или разработчиков.

Обеспечьте своим базам данных высокую производительность и отказоустойчивость — доверьте администрирование БД нам! Наши специалисты проводят миграцию и настраивают серверы БД и СУБД, строят кластеры, настраивают мониторинг и выполняют множество других задач по сопровождению IT-систем.


Распространенные ошибки в работе c СУБД

И если администрирование баз данных мы можем взять на себя, то выполнение запросов остается на стороне клиентов. Так, при работе с MySQL, PostgreSQL, MongoDB, MSSQL и другими СУБД при написании различных команд ошибаются как новички, так и опытные IT-специалисты.

Обращаем внимание! Для демонстрации типичных ошибок или некоторых возможностей СУБД ниже приведены абстрактные команды. Мы не призываем выполнять рассмотренные запросы в указанном виде. Возможности и команды могут отличаться в разных СУБД, и приведенные примеры актуальны преимущественно для MySQL.

1. Ошибки синтаксиса

Опечатки, пропущенные символы и лишние знаки в консольных командах — наиболее частые ошибки. К счастью, поправимые. При выполнении подобных запросов БД уведомит о несуществовании указанной команды или SQL укажет на ошибку. Скорректировать код при работе с БД также помогут онлайн-редакторы SQL.

2. Игнорирование условий

Зачастую пользователи не указывают условия в запросах, например для обновления и удаления данных. В результате такие команды могут уничтожить нужные данные. И вот как этого избегать. Например, для удаления строки со значением 2 в столбце ID можно выполнить:

DELETE FROM `USERS` WHERE `ID`= 2 LIMIT 1;

Условие WHERE указывает, что конкретно нужно удалить. LIMIT задает ограничение в одну строку — в данном случае его можно и не добавлять, потому что поле ID содержит уникальное значение. Но для подстраховки рекомендуется использовать этот оператор в СУБД, которые поддерживают его работу. 

Похожим образом работает и команда UPDATE. Чтобы обновить сразу несколько столбцов для одной записи, можно перечислить их через запятую:

UPDATE `USERS` SET `NAME` = `Cat`, `FOOD` = `Milk` WHERE `ID` = 3 LIMIT 1;

3. Некорректное использование операторов 

Нередко вместо WHERE ошибочно используется HAVING. WHERE фильтрует строки с данными и отсеивает ненужные. Затем GROUP BY формирует группы. И лишь потом оператор HAVING производит фильтрацию целых групп. Часто пользователи добавляют условие к HAVING, игнорируя WHERE. 

Например, нам нужно для условного столбца users отследить значения, начиная с первого июня, в которых содержится по 5 записей.  Корректный запрос может выглядеть так:

SELECT date, COUNT(*)
FROM users
WHERE date >= '2024-01-06'
GROUP BY date
HAVING COUNT(*) = 5  

4. Неправильное преобразование данных

СУБД могут по-разному преобразовывать данные при обработке одинаковых запросов. Например, при делении в PostgreSQL одного числа на другое ответ выводится в виде целого числа: 

SELECT a/b FROM demo
# столбец целых чисел

SELECT 1 / 2
# 0

При обработке аналогичного запроса MySQL выдаст дробное значение. Чтобы избежать искажения данных, нужно заранее изучить особенности конкретной СУБД. Также можно преобразовать данные, например при помощи команды:

SELECT CAST(1 AS FLOAT)/2 FROM demo;

5. Игнорирование отсутствия данных

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

Оператор COALESCE помогает отследить в перечне данных пропуски и прописать для них логику. Например, команда 

SELECT COALESCE (email, phone, 'Нет контактной информации') AS contact_info FROM Clients;

  • задействует еmail, если он есть, и телефон — при отсутствии почты; 
  • или добавляет фразу «Нет контактной информации», если нет никаких данных.

Рассмотрим частный сценарий использования оператора COALESCE. 

Планируется рассылка, которая начинается с переменной:

«Привет, имя_пользователя!». Если не разобраться с данными без почт, то у части пользователей письмо будет начинаться так: «Приветствуем, !». Исправить ситуацию поможет команда:

SELECT COALESCE(name, 'Уважаемый клиент') FROM Clients

Тогда пользователи, чьи имена у вас есть, получат персонализированное приветствие. А остальные увидят обращение «Дорогой друг». 

6. Нарушение порядка выполнения запросов

Условие WHERE в SQL выполняется раньше оператора SELECT. Игнорирование этого приводит к ошибкам при обработке запросов. При этом пользователи часто неправильно упрощают WHERE, особенно когда нужно учесть относительное изменение какого-то числового параметра. 

Например, проводится акция, и нужно проверить, сколько товаров изменило стоимость на 30% и более. Чтобы запрос был правильно обработан, его можно сформулировать следующим образом:

SELECT COUNT(*) AS changed_products_count

FROM products

WHERE ABS(new_price - old_price) / old_price >= 0.30;

где:

  • ABS(new_price - old_price) — вычисляет абсолютное изменение цены; 
  • / old_price — ABS(new_price - old_price) / old_price — вычисляет относительное изменение в процентах.
  • >= 0.30 — проверяет, изменилось ли значение на 30% или более.
  • COUNT(*) — подсчитывает количество товаров, которые соответствуют этому условию.

7. Пренебрежение индексами 

Индексы включают значения столбцов и ссылки на строки с ними. Их использование ускоряет фильтрацию по таблице и подбор нужных значений, но при этом замедляет выполнение некоторых команд: insert, update, delete. Поэтому нужно создавать индексы c точными критериями и на столбцах, по которым часто выполняется фильтрация. Например, если 90% вашей аудитории проживают в Беларуси, нет смысла использовать поле страны. А если вы готовитесь провести конференцию в определенном городе, например Бресте, добавление индекса city поможет точно выделить целевую аудиторию. Вот пример подобной команды:

CREATE INDEX idx_city ON Users(«Брест»);

8. Отсутствие логирования медленных запросов

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

В MySQL логирование медленных включается при помощи команды: 

SET GLOBAL slow_query_log = 'ON';

Можно установить лимит времени, например в 2 секунды, превышение которого будет считаться медленным для запроса: 

SET GLOBAL long_query_time = 2;

Указать место для хранения логов медленных запросов можно при помощи команды:

SET GLOBAL slow_query_log_file = '/path/to/your/slow-query.log';

где '/path/to/your/slow-query.log' — дериктория файла лога.

Чтобы изменения вступили в силу после перезапуска сервера, аналогичные строки нужно добавить в конфигурационный файл my.cnf:

[mysqld]

slow_query_log = 1

long_query_time = 2

slow_query_log_file = /path/to/your/slow-query.log

Проверить, активировано ли логирование медленных запросов поможет команда:

SHOW VARIABLES LIKE 'slow_query_log';

Некорректные SQL-запросы — не единственная сложность, которая может сказаться на производительности IT-инфраструктуры. Поэтому наши специалисты всегда готовы обеспечить администрирование ваших серверов, баз данных и сервисов. Заказывайте услуги MSP (Managed Service Provider) у нас и наслаждайтесь быстрой и надежной работой своих IT-систем!



Поделиться:
Подпишитесь на email-рассылку!

Будьте в курсе новостей. Отправляем полезные письма каждый месяц.

Пожалуйста, введите адрес электронной почты
Пожалуйста, подтвердите согласие с условиями обработки персональных данных.
article mailing picture
Вы подписались на нашу рассылку!

Скоро вы получите новое письмо.

article mailing picture