Добавил мобильную версию руководства по языку SQL и работе с базами данных на примере SQL Server
https://www.rustore.ru/catalog/app/com.metanit.sql_tutorial
#sql #database
https://www.rustore.ru/catalog/app/com.metanit.sql_tutorial
#sql #database
🔥16🤮3❤2🥰1👏1
20 распространенных рекомендаций по оптимизации SQL-запросов:
1. Индексы для шаблонов доступа к запросам (составные, селективные, покрывающие); не ориентируйтесь на количество строк; поддерживайте актуальность статистики.
2. Используйте EXISTS для проверки наличия записей; применяйте COUNT(*) только когда действительно нужен подсчёт.
3. Выбирайте конкретные столбцы явно; избегайте SELECT * для сокращения операций ввода-вывода и использования покрывающих индексов.
4. Предпочитайте SARG-предикаты (предикаты, допускающие использование индекса); переписывайте медленные коррелированные подзапросы с помощью JOIN/EXISTS.
5. Избегайте DISTINCT как временного решения; исправьте соединения/ключи; используйте его только когда действительно требуется удаление дубликатов.
6. Фильтрацию выполняйте в WHERE; резервируйте HAVING только для фильтрации после агрегации.
7. Используйте явные JOIN ... ON; избегайте неявных соединений в WHERE.
8. Применяйте пагинацию по ключам; избегайте OFFSET/LIMIT на больших наборах данных; для выборки используйте TABLESAMPLE (если доступно).
9. Используйте UNION ALL вместо UNION, когда дубликаты допустимы.
10. Заменяйте широкие OR-предикаты на UNION ALL только когда каждая ветвь может использовать разные индексы.
11. Планируйте выполнение тяжёлых запросов в периоды низкой нагрузки; применяйте ограничения ресурсов/очереди, если они доступны.
12. Избегайте OR в предикатах соединения; используйте вычисляемые столбцы или UNION ALL, когда это позволяет использовать поиск по индексу.
13. Используйте GROUP BY, когда нужны сгруппированные строки; применяйте оконные функции, когда требуется детализация строк с агрегатами.
14. Используйте производные/временные таблицы, когда они сокращают объём работы или добавляют статистику; остерегайтесь блокирующих спусков.
15. При массовой загрузке: отключайте/удаляйте некластерные индексы, выполняйте пакетную вставку, затем восстанавливайте; сохраняйте PK/кластерные индексы, когда это полезно.
16. Используйте материализованные представления для медленно меняющихся, ресурсоёмких агрегатов; планируйте обновление/недействительность.
17. Избегайте не-SARG-сравнений (например, <>) на столбцах с низкой селективностью; переписывайте в диапазоны, когда это возможно.
18. Минимизируйте коррелированные подзапросы над большими наборами; предпочитайте множественные соединения/EXISTS.
19. Выбирайте INNER вместо LEFT/RIGHT по семантике; INNER часто работает лучше, когда применимо.
20. Кешируйте повторяющиеся наборы результатов: временные таблицы (на сессию), кеш результатов или материализованные представления, с правилами актуальности.
#sql
1. Индексы для шаблонов доступа к запросам (составные, селективные, покрывающие); не ориентируйтесь на количество строк; поддерживайте актуальность статистики.
2. Используйте EXISTS для проверки наличия записей; применяйте COUNT(*) только когда действительно нужен подсчёт.
3. Выбирайте конкретные столбцы явно; избегайте SELECT * для сокращения операций ввода-вывода и использования покрывающих индексов.
4. Предпочитайте SARG-предикаты (предикаты, допускающие использование индекса); переписывайте медленные коррелированные подзапросы с помощью JOIN/EXISTS.
5. Избегайте DISTINCT как временного решения; исправьте соединения/ключи; используйте его только когда действительно требуется удаление дубликатов.
6. Фильтрацию выполняйте в WHERE; резервируйте HAVING только для фильтрации после агрегации.
7. Используйте явные JOIN ... ON; избегайте неявных соединений в WHERE.
8. Применяйте пагинацию по ключам; избегайте OFFSET/LIMIT на больших наборах данных; для выборки используйте TABLESAMPLE (если доступно).
9. Используйте UNION ALL вместо UNION, когда дубликаты допустимы.
10. Заменяйте широкие OR-предикаты на UNION ALL только когда каждая ветвь может использовать разные индексы.
11. Планируйте выполнение тяжёлых запросов в периоды низкой нагрузки; применяйте ограничения ресурсов/очереди, если они доступны.
12. Избегайте OR в предикатах соединения; используйте вычисляемые столбцы или UNION ALL, когда это позволяет использовать поиск по индексу.
13. Используйте GROUP BY, когда нужны сгруппированные строки; применяйте оконные функции, когда требуется детализация строк с агрегатами.
14. Используйте производные/временные таблицы, когда они сокращают объём работы или добавляют статистику; остерегайтесь блокирующих спусков.
15. При массовой загрузке: отключайте/удаляйте некластерные индексы, выполняйте пакетную вставку, затем восстанавливайте; сохраняйте PK/кластерные индексы, когда это полезно.
16. Используйте материализованные представления для медленно меняющихся, ресурсоёмких агрегатов; планируйте обновление/недействительность.
17. Избегайте не-SARG-сравнений (например, <>) на столбцах с низкой селективностью; переписывайте в диапазоны, когда это возможно.
18. Минимизируйте коррелированные подзапросы над большими наборами; предпочитайте множественные соединения/EXISTS.
19. Выбирайте INNER вместо LEFT/RIGHT по семантике; INNER часто работает лучше, когда применимо.
20. Кешируйте повторяющиеся наборы результатов: временные таблицы (на сессию), кеш результатов или материализованные представления, с правилами актуальности.
#sql
❤12🎄4👍3🔥3
Фантомные чтения
(описание к предыдущему посту)
В PostgreSQL и MySQL возможно, что одинаковые запросы SELECT в рамках одной транзакции могут возвращать разные результаты.
Рассмотрим пример с базой данных, в которой работают два клиента. Клиент A начинает транзакцию и выполняет SELECT всех заказов с общей ценой > 100 долларов. Пока он продолжает выполнять другие запросы, клиент B вставляет в таблицу новый заказ и фиксирует изменения (COMMIT). Наконец, клиент A снова запрашивает заказы с общей суммой > 100 долларов, но на этот раз видит новую строку, добавленную клиентом B!
Допускается ли такое поведение, зависит от настроенного уровня изоляции.
По умолчанию PostgreSQL использует уровень READ COMMITTED, который допускает фантомные чтения. Отдельные запросы получают согласованное представление базы данных, но между запросами в рамках одной транзакции могут наблюдаться изменения, зафиксированные другими транзакциями.
Как и PostgreSQL, MySQL имеет четыре настраиваемых пользователем уровня изоляции. Использование строгого уровня, такого как SERIALIZABLE, предотвращает фантомные чтения, в то время как более свободные уровни, такие как READ COMMITTED, допускают их (по умолчанию в MySQL используется REPEATABLE READ).
Почему бы не установить везде уровень SERIALIZABLE? Всё дело в производительности! Более строгие уровни требуют большего количества блокировок и снижают производительность, в то время как более свободные уровни обеспечивают более высокую производительность за счёт возможных несоответствий.
#sql #mysql #postgresql #database
(описание к предыдущему посту)
В PostgreSQL и MySQL возможно, что одинаковые запросы SELECT в рамках одной транзакции могут возвращать разные результаты.
Рассмотрим пример с базой данных, в которой работают два клиента. Клиент A начинает транзакцию и выполняет SELECT всех заказов с общей ценой > 100 долларов. Пока он продолжает выполнять другие запросы, клиент B вставляет в таблицу новый заказ и фиксирует изменения (COMMIT). Наконец, клиент A снова запрашивает заказы с общей суммой > 100 долларов, но на этот раз видит новую строку, добавленную клиентом B!
Допускается ли такое поведение, зависит от настроенного уровня изоляции.
По умолчанию PostgreSQL использует уровень READ COMMITTED, который допускает фантомные чтения. Отдельные запросы получают согласованное представление базы данных, но между запросами в рамках одной транзакции могут наблюдаться изменения, зафиксированные другими транзакциями.
Как и PostgreSQL, MySQL имеет четыре настраиваемых пользователем уровня изоляции. Использование строгого уровня, такого как SERIALIZABLE, предотвращает фантомные чтения, в то время как более свободные уровни, такие как READ COMMITTED, допускают их (по умолчанию в MySQL используется REPEATABLE READ).
Почему бы не установить везде уровень SERIALIZABLE? Всё дело в производительности! Более строгие уровни требуют большего количества блокировок и снижают производительность, в то время как более свободные уровни обеспечивают более высокую производительность за счёт возможных несоответствий.
#sql #mysql #postgresql #database
Telegram
METANIT.COM
Фантомные чтения
(подробное описание в следующем посте)
(подробное описание в следующем посте)
❤3