MySQL - Большая таблица показателей и высокая производительность запросов - Кэширование? - PullRequest
2 голосов
/ 22 марта 2011

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

В настоящее время у меня есть студия, где пользователи могут видетьэто использование и поведение, очевидно, отображаются в диаграммах и т. д. и т. п. Дело в том, что серьезно интенсивно , чтобы загрузить этот материал сейчас.У меня был проект, в котором работало 80 000 человек, и для загрузки статистики требовался возраст.

Теперь таблицы достаточно хорошо структурированы и проиндексированы для объединений и т. Д. У меня был совети искала пути обучения для лучшей практики, чтобы попытаться помочь лучше подготовиться к этому размеру данных.Но без гораздо большей возможности оптимизации запросов / таблиц как еще я могу ускорить этот интенсивный процесс? .

Я заметил, что большинство аналитиков позволяют просматривать до вчерашнего дня по умолчанию.Помогает ли это?

  1. Означает ли это, что статистика может быть кэширована query_cache на mysql?Если запрос постоянно заканчивается завтра (тем самым подсчитывая сегодняшнюю статистику), не будет ли он кэшироваться?
  2. Разумнее ли компилировать статические XML-файлы и т. Д. Каждый час, на которые можно ссылаться, вместо выполнения запросов каждый раз?
  3. Как еще?

Любые мысли очень приветствуются.

Ответы [ 5 ]

7 голосов
/ 22 марта 2011

Вы хотели бы разделить вещи на две базы данных. Один оптимизирован для вставки для захвата данных. И второй оптимизирован для поиска данных. Вы не можете сделать это с одной базой данных, обрабатывающей обе задачи. Оптимизация для тяжелой вставки данных означает сокращение до абсолютного минимума объема выполняемой индексации (в основном только первичных ключей), а удаление ключей снижает производительность, когда наступает время для интеллектуального анализа данных.

Итак ... две базы данных. Захватите все данные в оптимизированный для вставки. Затем запустите запланированное задание для сбора данных за день в другую базу данных и выполните там анализ.

В качестве побочного эффекта, отсюда и ограничение "до вчерашнего дня". Сегодняшние данные не будут доступны, поскольку они находятся в отдельной базе данных.

1 голос
/ 23 марта 2011

Вы точно не говорите, насколько большие таблицы, какие они таблицы, как они заполняются и как они используются.Итак, я просто собираюсь дать несколько случайных мыслей:)

Когда вы сообщаете о больших объемах данных, вы в основном ограничены скоростью вашей дисковой системы, то есть с какой скоростью ваши диски доставляютданные в MySQL.Этот показатель обычно измеряется в мегабайтах / секунду.Таким образом, если вы можете получить 100 МБ / с, то вы не сможете выполнить select sum () или count (*) для таблицы, превышающей 100 МБ, если вы хотите получить время отклика менее секунды (на мгновение полностью игнорируя кэш БД).Обратите внимание, что 100 МБ - это что-то вроде 20 миллионов записей с размером строки 50 байтов.
Это работает до определенного момента, и тогда все просто умирает.Обычно, когда размер базы данных становится больше доступной памяти, а количество одновременно работающих пользователей увеличивается.

Вам может потребоваться изучить возможность создания сводных таблиц , чтобы можно было уменьшитьколичество мегабайт, которое вам нужно просмотреть.Это лучше всего объяснить на примере.Предположим, что ваша текущая таблица показателей выглядит примерно так:

measures(
   user_id 
  ,timestamp
  ,action
)

Для каждого выполненного действия (вход в систему, выход из системы, нажатие на это, пердение, нажатие на это) вы сохраняете идентификатор пользователя и отметку временикогда это произошло.

Если вы хотите построить ежедневный номер входа в систему с начала года, вам придется выполнить подсчет (*) для всех 100 000 000 миллионов строк и сгруппировать по day(timestamp).

Вместо этого вы можете предоставить предварительно рассчитанную таблицу, такую ​​как:

daily_actions(
  day
 ,action
 ,occured
 ,primary key(day, action)
)

Эта таблица обычно загружается с чем-то вроде:

select day(timestamp)
      ,action
      ,count(*)
  from measures
 group
    by day(timestamp)
      ,action

Если бы у вас было 100 возможныхдействия, вам нужно всего 36 500 строк для хранения действий за весь год.Пользователи, использующие статистику, графики, отчеты и другие данные, не будут тяжелее ваших типичных транзакций OLTP.Конечно, вы также можете хранить его ежечасно (или вместо этого) и получать 876 000 строк в год.Вы также можете сообщать о недельных, месячных, временных или годовых показателях, используя приведенную выше таблицу.ЕСЛИ вы можете сгруппировать свои пользовательские действия по категориям действий, например, «Весело», «Не так весело», потенциально вредно »и« Неверно », вы можете уменьшить объем хранилища с 100 возможных действий до 4.

Очевидно, что ваши данные более сложны, чем эти, но вы почти всегда можете найти подходящее количество агрегированных таблиц, которые могут ответить практически на любой вопрос на высоком уровне агрегации., вы можете использовать все эти фильтры, и тогда вы можете обнаружить, что очень возможно выбрать из таблицы с наименьшей детализацией, используя определенный date и определенный action.

1 голос
/ 22 марта 2011

Марк Б прав: вы хотите отделить сбор данных от вашей системы аналитики / отчетности.

Условное название для этого - «хранилище данных» или подобное.Они, как правило, имеют очень разные схемы для вашей производственной базы данных - широко денормализованные или многомерные "звездные" схемы.

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

В любом случае, запустите базы данных сбора данных и отчетности на физически отдельном оборудовании.Если вы пойдете по пути хранилища данных, выделите много места на диске.

1 голос
/ 22 марта 2011

О дополнительном оборудовании не может быть и речи?Репликация данных на несколько рабов, вероятно, ускорит ситуацию в этой ситуации.Вы также можете использовать предложение Mark B для разделения базы данных, обновляя только ведомые устройства в нерабочее время, например, в течение ночи.

1 голос
/ 22 марта 2011

Если вам не нужно показывать результаты в реальном времени;Вы можете кэшировать результаты в Memcache, APC, Redis или equilevent с помощью кэша expire через один день.

Mysql будет кэшировать результаты в query_cache.Но вы не помните, MySQL очищает query_cache, когда таблица / строка была изменена.И его размер ограничен.

...