Oracle 11g — выполнение аналитических функций для миллионов строк

Мое приложение позволяет пользователям собирать данные измерений в рамках эксперимента и должно иметь возможность сообщать обо всех когда-либо проведенных измерениях.

Ниже приведена очень упрощенная версия таблиц, которые у меня есть:

CREATE TABLE EXPERIMENTS(
  EXPT_ID INT,
  EXPT_NAME VARCHAR2(255 CHAR)
);

CREATE TABLE USERS(
  USER_ID INT,
  EXPT_ID INT
);

CREATE TABLE SAMPLES(
  SAMPLE_ID INT,
  USER_ID INT
);

CREATE TABLE MEASUREMENTS(
  MEASUREMENT_ID INT,
  SAMPLE_ID INT,
  MEASUREMENT_PARAMETER_1 NUMBER,
  MEASUREMENT_PARAMETER_2 NUMBER
);

В моей базе 2000 экспериментов, в каждом из которых по 18 пользователей. У каждого пользователя есть 6 образцов для измерения, и он может выполнить 100 измерений для каждого образца.

Это означает, что в настоящее время в базе данных хранится 2000 * 18 * 6 * 100 = 21600000 измерений.

Я пытаюсь написать запрос, который будет получать AVG() параметров измерения 1 и 2 для каждого пользователя, что вернет около 36 000 строк.

Запрос, который у меня есть, очень медленный - я оставил его работать более 30 минут, и он ничего не возвращает. Мой вопрос: есть ли эффективный способ получить средние значения? И действительно ли возможно получить результаты для такого количества данных за разумное время, скажем, за 2 минуты? Или я нереалист?

Вот (опять же упрощенная версия) запрос, который у меня есть:

SELECT 
    E.EXPT_ID,
    U.USER_ID,
    AVG(MEASUREMENT_PARAMETER_1) AS AVG_1,
    AVG(MEASUREMENT_PARAMETER_2) AS AVG_2
FROM 
    EXPERIMENTS E, 
    USERS U, 
    SAMPLES S,
    MEASUREMENTS M
WHERE
 U.EXPT_ID = E.EXPT_ID
 AND S.USER_ID = U.USER_ID
 AND M.SAMPLE_ID = S.SAMPLE_ID
GROUP BY E.EXPT_ID, U.USER_ID

Это вернет строку для каждой комбинации expt_id/user_id и среднего значения двух параметров измерения.


person user1578653    schedule 25.07.2013    source источник
comment
Это агрегатная, а не аналитическая функция, она должна нормально работать с миллионами строк (как и аналитические функции). Вы не опубликовали ни одного DDL для индексов, поэтому сразу возникает подозрение, что у вас их нет... есть ли они и что это такое?   -  person Ben    schedule 25.07.2013


Ответы (1)


В любом случае для вашего запроса СУБД необходимо прочитать полную таблицу измерений. Это, безусловно, самая большая часть данных для чтения, и та часть, которая занимает больше всего времени, если запрос хорошо оптимизирован (об этом позже). Это означает, что минимальное время выполнения вашего запроса примерно равно времени, которое требуется для чтения полной таблицы измерений, где бы она ни хранилась. Вы можете получить приблизительную оценку, проверив объем данных (в МБ или ГБ) и проверив, сколько времени потребуется, чтобы прочитать этот объем данных с жесткого диска (или где хранится таблица). Если ваш запрос выполняется медленнее в 5 или более раз, вы можете быть уверены, что есть место для оптимизации.

Существует огромное количество информации (учебники, отдельные советы, которые могут оказаться бесценными, и списки общих практик) о том, как оптимизировать запросы оракула. Вы не получите всю эту информацию быстро. Но если вы предоставите план выполнения своего запроса (это то, что оптимизатор запросов Oracle считает лучшим способом выполнить ваш запрос), мы сможем определить шаги, которые можно оптимизировать, и предложить решения.

person Daniel S.    schedule 25.07.2013