2008-08-15 2 views
19

У меня есть большая база данных нормализованных данных заказа, которая становится очень медленной для запросов к отчетности. Многие из запросов, которые я использую в отчетах, объединяют пять или шесть таблиц и требуют изучения десятков или сотен тысяч строк.Что такое хороший способ денормализации базы данных mysql?

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

Любые идеи по подходу? Должен ли я начать с нескольких моих худших запросов и оттуда?

ответ

10

Я знаю больше о mssql о том, что mysql, но я не думаю, что количество объединений или количество строк, о которых вы говорите, должно вызывать слишком много проблем с правильными индексами на месте. Вы проанализировали план запроса, чтобы узнать, нет ли у вас каких-либо проблем?

http://dev.mysql.com/doc/refman/5.0/en/explain.html

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

Вот сайт, я обнаружил, что касается по теме:

http://www.meansandends.com/mysql-data-warehouse/?link_body%2Fbody=%7Bincl%3AAggregation%7D

Вот простой метод, который можно использовать, чтобы держать денормализации запросы просто, если вы просто делаете несколько в то время (и я не заменяю ваши OLTP-таблицы, просто создавая новую для целей отчетности). Допустим, у вас есть этот запрос в приложении:

select a.name, b.address from tbla a 
join tblb b on b.fk_a_id = a.id where a.id=1 

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

create table tbl_ab (a_id, a_name, b_address); 
-- (types elided) 

Обратите внимание на знак подчеркивание соответствуют псевдонимам таблиц, которые вы используете

insert tbl_ab select a.id, a.name, b.address from tbla a 
join tblb b on b.fk_a_id = a.id 
-- no where clause because you want everything 

Затем, чтобы исправить ваше приложение, чтобы использовать новую денормализованную таблицу, переключите точки для подчеркивания.

select a_name as name, b_address as address 
from tbl_ab where a_id = 1; 

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

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

[Еще одно редактирование] Не забывайте, что новые таблицы, которые вы создаете, также должны быть проиндексированы! Хорошая часть заключается в том, что вы можете индексировать контент вашего сердца и не беспокоиться о конкуренции блокировки обновлений, так как помимо вашей объемной вставки таблица увидит только избранные.

1

Я знаю, что это немного тангенциально, но вы пробовали посмотреть, есть ли больше индексов, которые вы можете добавить?

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

Мы используем DB2, и есть команда под названием db2expln и db2advis, первая будет указывать, используются ли таблицы для сканирования индексов, а вторая рекомендует индексы, которые вы можете добавить для повышения производительности. Я уверен, что MySQL имеет аналогичные инструменты ...

В любом случае, если это то, что вы еще не рассмотрели, оно многое помогло мне ... но если вы уже пошли по этому маршруту, Наверное, это не то, что вы ищете.

Другая возможность - это «материализованное представление» (или, как их называют, в DB2), которое позволяет указать таблицу, которая по существу построена из нескольких таблиц. Таким образом, вместо того, чтобы нормализовать фактические столбцы, вы можете предоставить этому представлению доступ к данным ... но я не знаю, оказывает ли это серьезное влияние на производительность на вставки/обновления/удаления (но если оно «материализовано», то оно должен помочь с выборами, поскольку значения физически хранятся отдельно).

1

MySQL 5 поддерживает views, что может быть полезно в этом сценарии. Похоже, вы уже много оптимизировали, но если нет, вы можете использовать синтаксис EXPLAIN MySQL, чтобы узнать, какие индексы фактически используются и что замедляет ваши запросы.

Что касается нормализации данных (независимо от того, используете ли вы представления или просто дублируете данные более эффективным образом), я думаю, что начиная с самых медленных запросов и прокладывая себе путь - это хороший подход.

0

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

2

В соответствии с некоторыми другими комментариями, я бы определенно посмотрел на вашу индексацию.

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

Чтобы дать представление об эффективности с хорошими индексами (включая многочисленные составные индексы), я могу запускать запросы, соединяющие 3 таблицы в нашей базе данных и получающие почти мгновенные результаты в большинстве случаев. Для более сложных отчетов большинство запросов выполняются менее чем за 10 секунд. Эти 3 таблицы имеют 33 миллиона, 110 миллионов и 140 миллионов строк соответственно. Обратите внимание, что мы также уже немного нормализовали их, чтобы ускорить наш самый распространенный запрос в базе данных.

Дополнительная информация о ваших таблицах и типах запросов к отчетности может дать дополнительные рекомендации.

0

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

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

0

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

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