2013-11-01 1 views
0

Я работаю над базой данных MySQL с 3 таблицами - workout_data, упражнениями и наборами таблиц. Я столкнулся с проблемами, связанными с созданием отчетов на основе этих трех таблиц.Создание отчета из 1 миллиона + записей в MySQL и отображение на странице Java JSP

Чтобы добавить дополнительную информацию, несколько наборов составляют упражнение, и ряд упражнений будет тренировкой. В настоящее время у меня есть метрики, из которых должен быть создан отчет из данных в этих таблицах. Я должен создавать отчеты за последние 42 дня, включая эту неделю. Запросы выполняются в течение длительного времени к тому времени, когда я получу отчет, присоединив эти таблицы.

Например, таблица наборов содержит более 1 миллиона записей только за последние 42 дня. Идентификатор в этой таблице - excercise_id в таблице упражнений. Идентификатор таблицы упражнений - workout_id в таблице workout_data.

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

Любые советы о том, как достичь этого?

 SELECT REPORTSETS.USER_ID,REPORTSETS.WORKOUT_LOG_ID, 
       REPORTSETS.SET_DATE,REPORTSETS.EXCERCISE_ID,REPORTSETS.SET_NUMBER 
      FROM EXCERCISES 
    INNER JOIN REPORTSETS ON EXCERCISES.ID=REPORTSETS.EXCERCISE_ID 
     where user_id=(select id from users where email='[email protected]') 
      and substr(set_date,1,10)='2013-10-29' 
     GROUP BY REPORTSETS.USER_ID,REPORTSETS.WORKOUT_LOG_ID, 
       REPORTSETS.SET_DATE,REPORTSETS.EXCERCISE_ID,REPORTSETS.SET_NUMBER 

ответ

1

две вещи:

Во-первых, есть следующий WHERE пункт положение, чтобы вытащить данные одного дня.

AND substr(set_date,1,10)='2013-10-29' 

Это окончательно поражает использование индекса на дату. Если set_date столбец имеет тип данных DATETIME, что вы хотите

AND set_date >= `2013-10-09` 
    AND set date < `2013-10-09` + INTERVAL 1 DAY 

Это позволит использовать сканирования диапазона по индексу на set_date.Мне кажется, что вам может понадобиться составной индекс на (user_id, set_date). Но вы должны обманывать EXPLAIN, чтобы выяснить, правильно ли это.

Во-вторых, вы неправильно используете GROUP BY. Это предложение бессмысленно, если в вашем запросе нет какой-либо сводной функции, такой как SUM() или GROUP_CONCAT(). Вы хотите ORDER BY?

+0

Если столбец set_date на самом деле является столбцом varchar, измените его на DATETIME. Шутки в сторону. Это поможет производительности * *. –

-1

Несомненно, предложения по настройке запроса помогут улучшить скорость запроса. Но я думаю, что основной момент здесь - то, что можно сделать с более чем 1 миллионом плюс записи до того, как сеанс завершится. Что делать, если у вас есть 2 или 3 миллиона записей, будет ли какая-то настройка производительности решить проблему? Я так не думаю. Итак:

1) Если вы хотите отобразить в браузере, используйте разбиение на страницы и запрос (например) первую 100 записей.
2) Если вы хотите сгенерировать отчет (например, pdf), используйте асинхронный метод (JMS)

+0

Я не думаю, что проблема заключается в том, как «отображать 1 м записей в браузере». Речь идет о времени, затраченном на создание отчета. – svz

+0

Но какой отчет он имеет в виду? Если это только таблица, показанная в браузере, то почему бы просто не работать с небольшим числом записей в первую очередь (я здесь ссылаюсь на разбивку на страницы) – ysp80

0

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

1

Комментарии на вашем SQL, которые вы можете посмотреть в:

1) У вас есть индекс по USER_ID и SET_DATE?

2) Ваш тип данных для SET_DATE выглядит неправильно, это varchar? Сохранение его в качестве даты означает, что db может оптимизировать ваш поиск намного эффективнее. В настоящий момент метод подстроки будет называться бесчисленным количеством раз для каждого запроса, поскольку он должен выполняться для каждой строки, возвращаемой первой частью вашего предложения where.

3) Действительно ли требуется группа? Если я не хочу что-то «группа по» части заявления не приносит ничего к столу не хватает;)

Смежные вопросы