Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

10 SQL ошибок, которые делают Java программисты

Anna | 3.06.2014 | нет комментариев

Java программисты мешают объектно-ориентированное и императивное мышление в зависимости от их яруса:
— мастерства (всякий может программировать императивно)
— догмы (образец для использования образцов где-либо и их именование)
— настроения (использовать правдивый объектный подход немножко труднее чем императивный)

Но всё меняется, когда Java разработчики пишут SQL код.
SQL — это декларативный язык, тот, что не имеет ничего всеобщего с объектно-ориентированным либо императивным мышлением. Дюже легко выразить запрос в SQ, но достаточно сложно выразить его правильно и оптимально. Разработчикам не только нужно переосмыслить их парадигму программирования, им необходимо ещё и думать в рамках теории множеств (set theory).

Ниже перечислены всеобщие ошибки, которые делают Java разработчики, использующие SQL в JDBC либо jOOQ (без определённого порядка). Для других 10 ошибок, глядите эту статью.

1. Позабыл о NULL

Недопонимание NULL — это скорее каждого самая огромная оплошность, которую Java разработчик может сделать, когда пишет SQL. Это может быть потому, что NULL ещё именуется UNKNOWN. Если бы он именовался легко UNKNOWN, его было бы проще осознать. Иная повод в том, что при приобретении данных и связывании переменных JDBC отражает SQL NULL в Java null. Это может привести к тому, что NULL = NULL (SQL) будет вести себя так же, как и null == null (JAVA).

Один из самых блестящих примеров заблуждения о NULL — это когда NULL предикаты применяются со строковым важным выражением.

Иная, больше специфическая задача возникает при отсутствии понимания значения NULL в NOT IN anti-joins.

Лекарство:
Тренируй себя. Ничего трудного — во время написания SQL неизменно думай о NULL:
— Данный предикат правилен касательно NULL?
— Влияет ли NULL на итог этой функции?

2. Обработка данных в памяти Java

Не многие Java программисты знают SQL дюже отлично. Беспричинный JOIN, необычный UNION и хорошо. А оконные функции? Группирующие комплекты? Многие Java разработчики загружают SQL данные в память, трансформируют их в какую-нибудь подходящую коллекцию и исполняют надобные вычисления на этих коллекциях с многословными циклическими конструкциями (по-крайней мере до совершенствования коллекций в JAVA 8).

Но некоторые SQL базы данных поддерживают добавочные (SQL эталон!) OLAP функции, которые подходят для этого отменнее и являются больше примитивными в написании. Один из примеров (не эталон) — это чудесныйоператор MODEL от Oracle. Легко дозволь БД сделать обработку и вытянуть итоги в память Java. Потому что, в конце концов, какой-то разумный парень теснее оптимизировал эти дорогие продукты. Выходит, применяя OLAP в БД, ты получаешь две вещи:
— Простоту. Скорее каждого, проще писать верно на SQL, чем на Java.
— Эффективность. БД скорее каждого будут стремительней чем твой алгорифм. И, что главней, тебе не придётся тащить миллионы записей по проводам.

Лекарство:
Всякий раз когда ты пишешь ориентированный на данные алгорифм с поддержкой Java, спрашивай себя: «Есть ли вероятность переложить эту работу на базу данных?»

3. Применение UNION взамен UNION ALL

Позор тому, что UNION ALL требует добавочного слова касательно UNION. Было бы гораздо отменнее, если бы SQL эталон был определён поддерживать:
— UNION (разрешает дублирование)
— UNION DISTINCT (убирает дублирование)

Удаление дубликатов не только реже применяется, оно ещё и достаточно медлительно на крупных итогах выборки, т.к. два под запроса обязаны быть упорядочены, и всякий кортеж должен быть сравнен с его дальнейшим кортежем.

Помни, что даже если SQL эталон определяет INTERSECT ALL и EXCEPT ALL, не всякая БД может реализовывать эти немного используемые комплекты операций.

Лекарство:
Думай, хотел ли ты написать UNION ALL всякий раз, когда пишешь UNION.

4. Применение JDBC для постраничной разбивки огромный выборки

Множество БД поддерживают какие-то средства для постраничной разбивки через LIMIT… OFFSET, TOP… START AT, OFFSET… FETCH операторов. В отсутствии поддержки этих операторов всё ещё есть вероятность наличия ROWNUM (Oracle) либо ROW_NUMBER() OVER() фильтрации (DB2, SQL Server 2008 и другие), которые гораздо стремительней разбивки в памяти. Это относится предпочтительно к огромным смещениям!

Лекарство:
Легко используйте эти операторы, либо инструмент(такой, как jOOQ), тот, что может имитировать эти операторы за вас.

5. Соединение данных в памяти Java

С ранних дней SQL и до сих пор некоторые Java программисты с тяжелым сердцем пишут JOINы. У них есть устаревший ужас того, что JOINы выполняются медлительно. Это может быть так, если оптимизатор убыточных затрат выбирает сделать вложенный цикл, загружая целые таблицы в память перед созданием ячеек присоединённой таблицы. Но это случается редко. С типичными предикатами, ограничениями, индексами, MERGE JOIN либо HASH JOIN операции выполняются дюже стремительно — всё зависит от правильных метаданных (Tom Kyte отлично написал об этом). Тем не менее, наверно ещё остались немногие Java разработчики, которые загружают две таблицы двумя отдельными запросами и соединяют их в памяти Java тем либо другим методом.

Лекарство:
Если бы выбираете из различных таблиц на разных этапах, подумайте ещё раз, внезапно вы можете выразить ваши запросы одним.

6. Применение DISTINCT либо UNION для удаления дубликатов из случайного декартова произведения

Из-за трудных соединений (JOIN) всякий разработчик может утратить след в значащих связях SQL запроса. Если определеннее, то при применении связи с комбинированными внешними ключами дозволено позабыть добавить значащие предикаты в JOIN… ON заявления. Это может привести к дублированию строк неизменно либо только в исключительных обстановках. Тогда некоторые разработчики могут добавить оператор DISTINCT для прекращения дублирования данных. Это не верно по трём причинам:
— Это может излечить итоги, но не причину. А ещё это может не решить итоги при граничных условиях.
— Это медлительно для крупных выборок. DISTINCT исполняет ORDER BY операцию для удаления дублирования.
— Это медлительно для крупных декартовых произведений которые всё равно будут загружены в память.

Лекарство:
Как правило, если Вы получаете неугодные дубликаты, пересмотрите свои JOIN предикаты. Видимо там где-то образовалось малое декартово произведение.

7. Избегание оператора MERGE

На самом деле это не оплошность, но, допустимо, это неимение познаний либо страхи сильного оператора MERGE. Некоторые БД знают другие формы UPSERT оператора, скажем MySQL ON DUPLICATE KEY UPDATE. На самом деле MERGE дюже силен, исключительно в БД, которые крепко расширяют SQL эталон, таких как SQL Server.

Лекарство:
Если Вы делаете UPSERT, выстраивая цепочку из INSERT и UPDATE либо SELECT… FOR UPDATE и INSERT/UPDATE, задумайтесь ещё раз. Взамен риска гонки за источниками, вы можете написать больше примитивное MERGE запрос.

8. Применение агрегатных функций взамен оконных функций

Перед возникновением оконных функций, исключительным средством для агрегации данных в SQL было применение GROUP BY совместно с агрегатными функциями в проекции. Это отлично работает в большинстве случаев, и если агрегированные данные обязаны быть наполнены обыкновенными данными, то сгруппированный запрос может быть написан в присоединённом под запросе.
Но SQL:2003 определяет оконные функции, которые реализованы многими подрядчиками БД. Оконные функции могут агрегировать данные на не группированных выборках. По факту, всякая оконная функция поддерживает свою собственную, самостоятельную PARTITION BY операцию, которая является хорошим инструментом для построения отчётов.

Применение оконных функций дозволит:
— Возвести больше читаемыйSQL (поменьше выделенных GROUP BY выражений в под запросах)
— Усовершенствовать продуктивность т.к. RDBMS может легче оптимизировать оконные функции

Лекарство:
Когда вы пишите GROUP BY выражение в под запросе, задумайтесь, может ли он быть выражен оконной функцией?

9. Применение сортировки в памяти при различных параметрах

Оператор ORDER BY поддерживает уйма типов выражений, включая CASE, тот, что может быть дюже пригоден при определении параметра сортировки. Вам никогда не следует сортировать данные в памяти Java только потому, что:
— SQL сортировка слишком неторопливая.
— SQL сортировка не может сделать этого.

Лекарство:
Если вы сортируете какие-либо SQL данные в памяти Java, задумайтесь, допустимо ли перенести эту сортировку в БД? Это отменно гармонирует со страничной разбивкой в БД.

10. Поочерёдная вставка множества записей

JDBC знает, что такое партия (batch), и Вам следует применять это. Не делайте INSERT тысяч записей одной за иной, создавая новейший PreparedStatement всякий раз. Если все ваши записи идут в одну таблицу, сделайте партию INSERT запросов с одним SQL запросом и несколькими объединяемыми комплектами данных. В зависимости от вашей БД и её конфигурации, что бы сберечь UNDO лог чистым, Вам может понадобиться делать commit через какое-то число вставленных записей.

Лекарство:
Неизменно используйте пакетную вставку крупных комплектов данных.

Несколько увлекательных книг на тему

— SQL Antipatterns by Bill Karwin
— SQL Performance Explained by Markus Winand

Хотели бы Вы увидеть перевод продолжения статьи?

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

Проголосовало 64 человека. Воздержалось 20 человек.

Источник: programmingmaster.ru

Оставить комментарий
БАЗА ЗНАНИЙ
СЛУЧАЙНАЯ СТАТЬЯ
СЛУЧАЙНЫЙ БЛОГ
СЛУЧАЙНЫЙ МОД
СЛУЧАЙНЫЙ СКИН
НОВЫЕ МОДЫ
НОВЫЕ СКИНЫ
НАКОПЛЕННЫЙ ОПЫТ
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB