При каких условиях SELECT по ПЕРВИЧНОМУ КЛЮЧУ будет медленным? - PullRequest
8 голосов
/ 28 июля 2010

Устранение некоторых проблем с производительностью БД в довольно типичном приложении EclipseLink / JPA.

Я вижу частые запросы, которые занимают 25-100 мс. Это простые запросы, просто выбирая все столбцы из таблицы, где ее первичный ключ равен значению. Они не должны быть медленными.

Я просматриваю время запроса в журнале postgres, используя log_min_duration_statement, так что это должно устранить любые издержки сети или приложения.

Этот запрос не медленный, но он используется очень часто.

Почему выбор * по первичному ключу будет медленным? Это специфично для postgres или это общая проблема БД? Как я могу ускорить это? В общем? Для postgres?

Пример запроса из журнала pg:

2010-07-28 08:19:08 PDT - LOG:  duration: 61.405 ms  statement: EXECUTE <unnamed>  [PREPARE:  SELECT coded_ele
ment_key, code_system, code_system_label, description, label, code, concept_key, alternate_code_key FROM coded
_element WHERE (coded_element_key = $1)]

Таблица содержит около 3,5 миллионов строк.

Я также запустил EXPLAIN и EXPLAIN ANALYZE для этого запроса, он выполняет только сканирование индекса.

Ответы [ 5 ]

4 голосов
/ 28 июля 2010

Выбор * делает вашу базу данных более сложной, и, как правило, это плохая практика. На стеке есть множество вопросов / ответов об этом.

Вы пробовали заменить * именами полей?

2 голосов
/ 28 июля 2010

Ну, я немного знаю о postgres SQL, поэтому я дам вам совет по MS SQL Server, который может быть применим.

В MS SQL Server есть понятие «индекс кластера»который является физическим расположением данных на диске.Хорошо использовать поле, в котором вы будете искать диапазон значений (в основном это поля даты).Не очень полезно, если вы ищете точное значение (например, поиск по первичному ключу).Однако иногда индекс первичного ключа непреднамеренно устанавливается как кластеризованный индекс.Это делает поиск индекса в просмотре таблицы.

2 голосов
/ 28 июля 2010

Не могли бы вы получить какое-то утверждение о блокировке?Какие блокировки вы используете при выполнении этих запросов?

1 голос
/ 28 июля 2010

Строка необычно большая или содержит большие двоичные объекты и большие двоичные поля?

Это напрямую через консоль или этот запрос выполняется через некоторый API доступа к данным, такой как jdbc или ADO.NET?Вы упоминаете JPA, который выглядит как API доступа к данным.Для коротких запросов API доступа к данным занимает больший процент времени выполнения - создание команды, создание объектов для хранения строк и ячеек и т. Д.

1 голос
/ 28 июля 2010

select * почти всегда очень плохая идея.

  1. Если порядок полей изменится, это нарушит ваш код. Согласно комментариям, это не так.это не важно, учитывая используемую вами библиотеку абстракций.
  2. Вы, вероятно, возвращаете из таблицы больше данных, чем вам на самом деле нужно.Выбор конкретных полей, которые вы хотите, может сэкономить время передачи.

25 мс - это нижняя граница, которую вы увидите почти при любом виде SQL-запроса - это только два обращения к диску!Возможно, вы захотите найти способы уменьшить количество раз выполнения запроса, а не пытаться оптимизировать запрос.

...