powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Использование MySQL для хранилища данных
41 сообщений из 41, показаны все 2 страниц
Использование MySQL для хранилища данных
    #38538203
Kouki
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте. Необходимо создать хранилище данных, примерные параметры которого следующие: максимальный размер таблицы фактов 30-40 млн записей (2-2,5 Гб), число измерений около 20. Для этой цели выбрал MySQL, но пока не могу добиться приемлемой производительности: аналитические запросы выполняются в среднем по 60-80 секунд. Для теста использую виртуальную машину (2 ядра, 2 гб памяти), все на движке MyISAM. Профилирование показывает, что почти все время занимает копирование временной таблицы на жесткий диск, а также что вместо индексов используется полное сканирование.
Хотел бы узнать, какие аппаратные показатели будут теоретически достаточны для хд с заданными объемами и как настроить MySQL на эффективную обработку аналитических запросов? Число одновременных пользователей будет не больше 1-2. Можно ли сделать, что бы все операции чтения производились в памяти?
...
Рейтинг: 0 / 0
Использование MySQL для хранилища данных
    #38538211
Kouki
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вот некоторые параметры my.cnf (взяты из my-huge.cnf).
key_buffer_size = 384M
sort_buffer_size = 2M
read_buffer_size = 2M
myisam_sort_buffer_size = 64M
max_heap_table_size = 1024M
tmp_table_size = 1024M
...
Рейтинг: 0 / 0
Использование MySQL для хранилища данных
    #38538217
bochkov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
запросы к базе кривые
...
Рейтинг: 0 / 0
Использование MySQL для хранилища данных
    #38538219
Kouki
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
bochkov,
Запросы формирует Mondrian от Pentaho. Сомнительно, что они кривые.
...
Рейтинг: 0 / 0
Использование MySQL для хранилища данных
    #38538249
OlegROA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
1. Обычно, в таких случаях приводят описание таблиц, что бы можно было правильно осмыслить Вашу фразу "вместо индексов используется полное сканирование".
2. И, естественно, сразу же напрашивается реплика - "запрос в студию". Т.е., приведите хотя-бы самый простой запрос, который выполняется долго и, по показаниям профайлера, не использует имеющиеся индексы.
3. Если хотите все загнать в память, то для такой базы нужно, как минимум, 6-8 гигов памяти и соответственно увеличить нужные параметры. Ну, или поставьте SSD.
4. Использование OLAP-сервера еще не гарантирует генерацию оптимальных запросов.
...
Рейтинг: 0 / 0
Использование MySQL для хранилища данных
    #38538255
netwind
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Чтобы построить аналитику по всем данным, нужно просто построить аналитику по всем данным и считать все эти данные.
Чего тут удивляться?
...
Рейтинг: 0 / 0
Использование MySQL для хранилища данных
    #38538264
OlegROA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В том-то и дело, что реплику ТС про "аналитические запросы" можно интрепретировать по разному - от простейшей аналитики типа "сумма всех продаж по конкретному клиенту" до сложных отчетов, которые, обычно, формируются не одним запросом, а подготавливаются в хранимке или "тянуться" промежуточные данные на клиента, где в таблицах в памяти все и формируется в готовые отчеты.
И, что бы не гадать, я и попросил у ТС пункт 2.
...
Рейтинг: 0 / 0
Использование MySQL для хранилища данных
    #38538318
Kouki
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вот таблица поменьше (7 млн записей):
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
CREATE TABLE AbonentWH.Payment (
  PaymentID int(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'Идентификатор оплаты',
  PublicUtilitiesID tinyint(4) UNSIGNED NOT NULL COMMENT 'Идентификатор организации ЖКХ',
  PaymentSourceID smallint(6) UNSIGNED NOT NULL COMMENT 'Идентификатор источника оплаты',
  PaymentMethodID smallint(6) UNSIGNED NOT NULL COMMENT 'Идентификатор способа оплаты',
  DateDiscountID smallint(6) UNSIGNED NOT NULL COMMENT 'Идентификатор даты учета оплаты',
  DatePaymentID smallint(6) UNSIGNED NOT NULL COMMENT 'Идентификатор фактической даты оплаты',
  DateID smallint(6) UNSIGNED NOT NULL COMMENT 'Идентификатор даты, за которую осуществлена оплата',
  ServiceID smallint(6) UNSIGNED NOT NULL COMMENT 'Идентификатор услуги',
  AbonentID int(11) UNSIGNED NOT NULL COMMENT 'Идентификатор абонента',
  SubsidyID tinyint(4) UNSIGNED NOT NULL COMMENT 'Идентификатор субсидирования',
  ContractorID smallint(6) UNSIGNED NOT NULL COMMENT 'Идентификатор внешней организации',
  PaymentTypeID tinyint(4) UNSIGNED NOT NULL COMMENT 'Идентификатор типа оплаты',
  PrimaryDocumentCode int(11) UNSIGNED NOT NULL COMMENT 'Код первичного документа об оплате',
  TicketCode int(11) UNSIGNED NOT NULL COMMENT 'Код квитанции об оплате',
  DiscountDay tinyint(4) UNSIGNED NOT NULL COMMENT 'День учета оплаты',
  DiscountMonth tinyint(4) UNSIGNED NOT NULL COMMENT 'Месяц учета оплаты',
  DiscountYear smallint(6) UNSIGNED NOT NULL COMMENT 'Год учета оплаты',
  PaymentSum decimal(18, 4) NOT NULL COMMENT 'Сумма оплаты',
  RegistrationDate date NOT NULL COMMENT 'Дата регистрации записи в ХД',
  PRIMARY KEY (PaymentID),
  INDEX IDX_Payment_AbonentID (AbonentID),
  INDEX IDX_Payment_ContractorID (ContractorID),
  INDEX IDX_Payment_DateDiscountID (DateDiscountID),
  INDEX IDX_Payment_DateID (DateID),
  INDEX IDX_Payment_DatePaymentID (DatePaymentID),
  INDEX IDX_Payment_PaymentMethodID (PaymentMethodID),
  INDEX IDX_Payment_PaymentSourceID (PaymentSourceID),
  INDEX IDX_Payment_PaymentTypeID (PaymentTypeID),
  INDEX IDX_Payment_ServiceID (ServiceID),
  INDEX IDX_Payment_SubsidyID (SubsidyID)
)
ENGINE = MYISAM



Пример запроса:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
select
    `Service`.`ResourceName` as `c0`,
    `Service`.`ServiceName` as `c1`,
    `PaymentSource`.`PaymentSourceName` as `c2`,
    `Date_2`.`Year` as `c3`,
    `Date_2`.`Quarter` as `c4`,
    `Date_2`.`Month` as `c5`,
    `Date_2`.`Day` as `c6`,
    sum(`Payment`.`PaymentSum`) as `m0`,
    count(distinct `Payment`.`TicketCode`) as `m1`
from
    `Service` as `Service`,
    `Payment` as `Payment`,
    `PaymentSource` as `PaymentSource`,
    `Date` as `Date_2`
where
    `Payment`.`ServiceID` = `Service`.`ServiceID`
and
    `Service`.`ResourceName` in ('Водоотведение', 'Горячее водоснабжение', 'Холодное водоснабжение')
and
    `Service`.`ServiceName` in ('Водоотведение', 'Горячая вода', 'Холодная вода')
and
    `Payment`.`PaymentSourceID` = `PaymentSource`.`PaymentSourceID`
and
    `PaymentSource`.`PaymentSourceName` in ('КВЦ', 'Касса', 'Ошибочно проведенная оплата', 'Перерасчет квитанций', 'По суду', 'Реестры оплаты из ЦОКП', 'Списание по приказу')
and
    `Payment`.`DateDiscountID` = `Date_2`.`DateID`
and
    `Date_2`.`Year` = 2013
and
    `Date_2`.`Quarter` = 3
and
    `Date_2`.`Month` = '9'
group by
    `Service`.`ResourceName`,
    `Service`.`ServiceName`,
    `PaymentSource`.`PaymentSourceName`,
    `Date_2`.`Year`,
    `Date_2`.`Quarter`,
    `Date_2`.`Month`,
    `Date_2`.`Day`


ПрофилированиеSorting result 9,488223 83,72
Copying to tmp table 1,447273 12,77
Sending data 0,344958 3,04
statistics 0,038657 0,34
removing tmp table 0,009193 0,08
Creating tmp table 0,003196 0,03
freeing items 0,000843 0,01
starting 0,000168 0,00
init 0,000074 0,00
end 0,000071 0,00
preparing 0,000070 0,00
Opening tables 0,000058 0,00
optimizing 0,000025 0,00
checking permissions 0,000016 0,00
System lock 0,000015 0,00
closing tables 0,000014 0,00
logging slow query 0,000006 0,00
executing 0,000005 0,00
cleaning up 0,000004 0,00
query end 0,000002 0,00

План
Код: plaintext
1.
2.
3.
Date_2	1	SIMPLE	index_merge	PRIMARY,IDX_Date_Quarter,IDX_Date_Year,IDX_Date_Month	IDX_Date_Year,IDX_Date_Month	2,1		32	Using intersect(IDX_Date_Year,IDX_Date_Month); Using where; Using temporary; Using filesort
Payment	1	SIMPLE	ref	IDX_Payment_DateDiscountID,IDX_Payment_PaymentSourceID,IDX_Payment_ServiceID	IDX_Payment_DateDiscountID	2	AbonentWH.Date_2.DateID	12104	
Service	1	SIMPLE	eq_ref	PRIMARY	PRIMARY	2	AbonentWH.Payment.ServiceID	1	Using where
PaymentSource	1	SIMPLE	eq_ref	PRIMARY	PRIMARY	2	AbonentWH.Payment.PaymentSourceID	1	Using where
...
Рейтинг: 0 / 0
Использование MySQL для хранилища данных
    #38538322
Kouki
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здесь часть индексов используется и копирование на диск меньше, обычно выходит хуже.
И еще есть такая проблема, что почему-то при запуске некоторых запросов резко переполняется папка временных файлов /tmp (за секунды создаются два файла по 3.1 Гб) и отображается ошибка.
...
Рейтинг: 0 / 0
Использование MySQL для хранилища данных
    #38538431
Фотография ScareCrow
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
автор `Date_2`.`Year` = 2013
and
`Date_2`.`Quarter` = 3
and
`Date_2`.`Month` = '9'
как нагнуть сервер. эпопея в трех частях.
...
Рейтинг: 0 / 0
Использование MySQL для хранилища данных
    #38538444
Фотография javajdbc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kikki,

Перечитайте секцию оптимизации Мондриана.
Например , посмотрите в следуюших направлениях:

1. СервисНайм и РесорсеНайм -- проанализивуйте,
если они строго завязаны то можно поставить
оптимизационный хинт "ДепендентМесурмент"
и убрать одно из них из Групбая

2. Добавьте ( если нет ) во временую ось полную дату
(кроме размазки по году-месяцу-дню).
Потом аналитику вытаскивать не по набору год-месяц-день
а по конкретному дню

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

Если МОндриан будет брыкатся -- зафорсить индекс на Дату а не на
интерсект
...
Рейтинг: 0 / 0
Использование MySQL для хранилища данных
    #38538448
Фотография javajdbc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
`PaymentSource`.`PaymentSourceName` in ('КВЦ', 'Касса', 'Ошибочно проведенная оплата', 'Перерасчет квитанций', 'По суду', 'Реестры оплаты из ЦОКП', 'Списание по приказу')

это полный набор значений? если полный, то
его надо убрать вообше как филтр.
...
Рейтинг: 0 / 0
Использование MySQL для хранилища данных
    #38538450
Фотография javajdbc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
если таки все равно медлено,
прочитайте секцию про пре-агрегаты.
...
Рейтинг: 0 / 0
Использование MySQL для хранилища данных
    #38538520
Kouki
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
javajdbc,
Спасибо. Если вы имеете в виду parent-child иерархию сделать, то мондриан позволяет только одноуровневые иерархии, также в кубах, которые содержат parent-child иерархии нельзя использовать distinct-count показатели, которые мне нужны.
PaymentSource находится не в фильтре, т.к. мне нужно визуально отобразить суммы по всем источникам оплаты, а не просто посчитать их.
Дискуссия переместилась в сторону мондриана, а хотелось обсудить настройку производительности mysql для задач olap. На какие настройки обратить внимание? Почему при некоторых запросах может происходить переполнение папки /tmp (заполняется 7 гб при объеме таблицы, к которой происходит запрос в 350 мб и индексов к ней 500 мб)?
...
Рейтинг: 0 / 0
Использование MySQL для хранилища данных
    #38538523
Kouki
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
И стоит ли подумать о секционировании? И по какому критерию в этом случае делать секции для приведенной таблицы? По полю DateDiscountID, которое чаще всего используется?
...
Рейтинг: 0 / 0
Использование MySQL для хранилища данных
    #38538533
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Koukibochkov,
Запросы формирует Mondrian от Pentaho. Сомнительно, что они кривые.

:-)
...
Рейтинг: 0 / 0
Использование MySQL для хранилища данных
    #38538582
Фотография javajdbc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
>> Если вы имеете в виду parent-child иерархию сделать, то мондриан позволяет только одноуровневые иерархии, также в кубах, которые содержат parent-child иерархии нельзя использовать distinct-count показатели, которые мне нужны.

Нет я предлагаю в уже имеюшейся звездной таблице ДАТЫ добявить еше одно поле
ГОД_МЕСЯЦ и тогда конкретно этот СКЛ избавится от

and `Date_2`.`Year` = 2013
and `Date_2`.`Quarter` = 3
and `Date_2`.`Month` = '9'

и останется...

date_2.year_mon = '2013-09'

...с одиночным индексом

>> PaymentSource находится не в фильтре, т.к. мне нужно визуально отобразить суммы по всем источникам оплаты, а не просто посчитать их.

если....

and `PaymentSource`.`PaymentSourceName` in ('КВЦ', 'Касса', 'Ошибочно проведенная оплата', 'Перерасчет квитанций', 'По суду', 'Реестры оплаты из ЦОКП', 'Списание по приказу')

... есть список ВСЕХ имеюшиеся PaymentSourceName, то эта строчка вообше не нужна
в WHERE секции, а только в GROUP BY секции

Как имено сделать оптимизацию такого рода в генераторе, я не в курсе.

>> Дискуссия переместилась в сторону мондриана, а хотелось обсудить настройку производительности mysql для задач olap. На какие настройки обратить внимание?

В первую очередь надо попытатся упростить запрос на лОГИЧЕСКОМ уровне,
на уровне здравых запросов и с помошью оптимизции Мондриана.

Потом надо понять/оценить узкие места и только потом, после логическогой оптимизации
смотреть на настройки мускл-а

>> Почему при некоторых запросах может происходить переполнение папки /tmp (заполняется 7 гб при объеме таблицы, к которой происходит запрос в 350 мб и индексов к ней 500 мб)?

может быть сбился/потерялся/не используется индекс и
произошел полный кортезиан 350МБ с табличкой на
всево-лишь 20 записей -- и вот вам 7ГБ каких-нибудь временых данных.
...
Рейтинг: 0 / 0
Использование MySQL для хранилища данных
    #38538583
Фотография javajdbc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KoukiВот таблица поменьше (7 млн записей):

CREATE TABLE AbonentWH.Payment (
PaymentID int(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'Идентификатор оплаты',
PublicUtilitiesID tinyint(4) UNSIGNED NOT NULL COMMENT 'Идентификатор организации ЖКХ',
PaymentSourceID smallint(6) UNSIGNED NOT NULL COMMENT 'Идентификатор источника оплаты',
PaymentMethodID smallint(6) UNSIGNED NOT NULL COMMENT 'Идентификатор способа оплаты',
DateDiscountID smallint(6) UNSIGNED NOT NULL COMMENT 'Идентификатор даты учета оплаты',
DatePaymentID smallint(6) UNSIGNED NOT NULL COMMENT 'Идентификатор фактической даты оплаты',
DateID smallint(6) UNSIGNED NOT NULL COMMENT 'Идентификатор даты, за которую осуществлена оплата',
ServiceID smallint(6) UNSIGNED NOT NULL COMMENT 'Идентификатор услуги',
AbonentID int(11) UNSIGNED NOT NULL COMMENT 'Идентификатор абонента',
SubsidyID tinyint(4) UNSIGNED NOT NULL COMMENT 'Идентификатор субсидирования',
ContractorID smallint(6) UNSIGNED NOT NULL COMMENT 'Идентификатор внешней организации',
PaymentTypeID tinyint(4) UNSIGNED NOT NULL COMMENT 'Идентификатор типа оплаты',
PrimaryDocumentCode int(11) UNSIGNED NOT NULL COMMENT 'Код первичного документа об оплате',
TicketCode int(11) UNSIGNED NOT NULL COMMENT 'Код квитанции об оплате',
DiscountDay tinyint(4) UNSIGNED NOT NULL COMMENT 'День учета оплаты',
DiscountMonth tinyint(4) UNSIGNED NOT NULL COMMENT 'Месяц учета оплаты',
DiscountYear smallint(6) UNSIGNED NOT NULL COMMENT 'Год учета оплаты',
PaymentSum decimal(18, 4) NOT NULL COMMENT 'Сумма оплаты',
RegistrationDate date NOT NULL COMMENT 'Дата регистрации записи в ХД',
PRIMARY KEY (PaymentID),
INDEX IDX_Payment_AbonentID (AbonentID),
INDEX IDX_Payment_ContractorID (ContractorID),
INDEX IDX_Payment_DateDiscountID (DateDiscountID),
INDEX IDX_Payment_DateID (DateID),
INDEX IDX_Payment_DatePaymentID (DatePaymentID),
INDEX IDX_Payment_PaymentMethodID (PaymentMethodID),
INDEX IDX_Payment_PaymentSourceID (PaymentSourceID),
INDEX IDX_Payment_PaymentTypeID (PaymentTypeID),
INDEX IDX_Payment_ServiceID (ServiceID),
INDEX IDX_Payment_SubsidyID (SubsidyID)
)
ENGINE = MYISAM



Пример запроса:

select
`Service`.`ResourceName` as `c0`,
`Service`.`ServiceName` as `c1`,
`PaymentSource`.`PaymentSourceName` as `c2`,
`Date_2`.`Year` as `c3`,
`Date_2`.`Quarter` as `c4`,
`Date_2`.`Month` as `c5`,
`Date_2`.`Day` as `c6`,
sum(`Payment`.`PaymentSum`) as `m0`,
count(distinct `Payment`.`TicketCode`) as `m1`
from
`Service` as `Service`,
`Payment` as `Payment`,
`PaymentSource` as `PaymentSource`,
`Date` as `Date_2`
where
`Payment`.`ServiceID` = `Service`.`ServiceID`
and
`Service`.`ResourceName` in ('Водоотведение', 'Горячее водоснабжение', 'Холодное водоснабжение')
and
`Service`.`ServiceName` in ('Водоотведение', 'Горячая вода', 'Холодная вода')
and
`Payment`.`PaymentSourceID` = `PaymentSource`.`PaymentSourceID`
and
`PaymentSource`.`PaymentSourceName` in ('КВЦ', 'Касса', 'Ошибочно проведенная оплата', 'Перерасчет квитанций', 'По суду', 'Реестры оплаты из ЦОКП', 'Списание по приказу')
and
`Payment`.`DateDiscountID` = `Date_2`.`DateID`

AND Date_2.yesr_mon = '2013-03'

and
`Date_2`.`Year` = 2013
and
`Date_2`.`Quarter` = 3
and
`Date_2`.`Month` = '9'
group by
`Service`.`ResourceName`,
`Service`.`ServiceName`,
`PaymentSource`.`PaymentSourceName`,
`Date_2`.`Year`,
`Date_2`.`Quarter`,
`Date_2`.`Month`,
`Date_2`.`Day`


ПрофилированиеSorting result 9,488223 83,72
Copying to tmp table 1,447273 12,77
Sending data 0,344958 3,04
statistics 0,038657 0,34
removing tmp table 0,009193 0,08
Creating tmp table 0,003196 0,03
freeing items 0,000843 0,01
starting 0,000168 0,00
init 0,000074 0,00
end 0,000071 0,00
preparing 0,000070 0,00
Opening tables 0,000058 0,00
optimizing 0,000025 0,00
checking permissions 0,000016 0,00
System lock 0,000015 0,00
closing tables 0,000014 0,00
logging slow query 0,000006 0,00
executing 0,000005 0,00
cleaning up 0,000004 0,00
query end 0,000002 0,00

План
Код: plaintext
1.
2.
3.
Date_2	1	SIMPLE	index_merge	PRIMARY,IDX_Date_Quarter,IDX_Date_Year,IDX_Date_Month	IDX_Date_Year,IDX_Date_Month	2,1		32	Using intersect(IDX_Date_Year,IDX_Date_Month); Using where; Using temporary; Using filesort
Payment	1	SIMPLE	ref	IDX_Payment_DateDiscountID,IDX_Payment_PaymentSourceID,IDX_Payment_ServiceID	IDX_Payment_DateDiscountID	2	AbonentWH.Date_2.DateID	12104	
Service	1	SIMPLE	eq_ref	PRIMARY	PRIMARY	2	AbonentWH.Payment.ServiceID	1	Using where
PaymentSource	1	SIMPLE	eq_ref	PRIMARY	PRIMARY	2	AbonentWH.Payment.PaymentSourceID	1	Using where



судя по плану у вас 12К записей в день. в запросе 1 месяц - 30 дней , значит 400К записей.
Основное время 10 сец, 83,72% занял сортинг -- похоже на сортировку для
группировки на диске.

Опятже, эта проблема с сортировкой может пропасть после
Мондриан оптимизации (например с использованием сквозного индекса по YEAR_MON).
А если останется -- надо думать про настройки сервера (наконецто!).

Тут надо попросить более опытных товаришей в плане расчетов
ресурсов: как настроить сорт буфера для
400К записей типа AbonentWH.Payment

(очевидно надо заменить 3 поля для ДискаунтДатеДей/Монс/Уеар
на ДискаунтДатеИД, или это разные ДИскаунты???)

Сами тоже можете попробовать настроить буфера с помошью утилиты:

wget mysqltuner.pl
perl mysqltuner.pl
...
Рейтинг: 0 / 0
Использование MySQL для хранилища данных
    #38540453
Kouki
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
javajdbc,
DateDiscountID уже есть в таблице Payment, посмотрите. Через него и происходит связь с таблицей Date. Поля DiscountYear/Month/Day не используются в запросах.
...
Рейтинг: 0 / 0
Использование MySQL для хранилища данных
    #38541032
Фотография javajdbc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Koukijavajdbc,
DateDiscountID уже есть в таблице Payment, посмотрите. Через него и происходит связь с таблицей Date. Поля DiscountYear/Month/Day не используются в запросах.

Я видел что там есть и ИД и отдельные значения.
Если это одно и тоже, то отдельные значения надо удалить
чтобы сократить размер (хоть немного).
Но может это были разные дискаунты, было непонятно до вашего уточнения.
...
Рейтинг: 0 / 0
Использование MySQL для хранилища данных
    #38541145
Aleksandr Kuzminsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
KoukiЗдравствуйте. Необходимо создать хранилище данных, примерные параметры которого следующие: максимальный размер таблицы фактов 30-40 млн записей (2-2,5 Гб), число измерений около 20. Для этой цели выбрал MySQL, но пока не могу добиться приемлемой производительности: аналитические запросы выполняются в среднем по 60-80 секунд. Для теста использую виртуальную машину (2 ядра, 2 гб памяти), все на движке MyISAM. Профилирование показывает, что почти все время занимает копирование временной таблицы на жесткий диск, а также что вместо индексов используется полное сканирование.
Хотел бы узнать, какие аппаратные показатели будут теоретически достаточны для хд с заданными объемами и как настроить MySQL на эффективную обработку аналитических запросов? Число одновременных пользователей будет не больше 1-2. Можно ли сделать, что бы все операции чтения производились в памяти?

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

Все таблицы надо перевести в InnoDB. Сегодня нет смысла использовать MyISAM. Дело в том, что в MyISAM кешируются только индексы (key_buffer), данные будут читаться с диска. И несмотря на то, что есть кеш файловой системы, он все равно хуже, чем специализированный кеш InnoDB (innodb_buffer). То есть, таблицы в InnoDB, для буфер пула выделите как минимум 2.5G памяти (соответственно, сервер должен иметь достаточно памяти).

Временные таблицы - это результат плохих запросов и плохих индексов. Если проблему не получится исправить индексами укажите временную (tmpdir) директорию на RAM диске ( чтто-то вроде /dev/shm/mysql)
...
Рейтинг: 0 / 0
Использование MySQL для хранилища данных
    #38541149
Aleksandr Kuzminsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Koukikey_buffer_size = 384M


Не используйте MyISAM.

Koukisort_buffer_size = 2M


OK

Koukiread_buffer_size = 2M


OK

Koukimax_heap_table_size = 1024M
tmp_table_size = 1024M


Аккуратно с этими буферами. Если MySQL начнет свопиться - все умрет. Я бы оставил их равными дефолту и пытался избавляться от временных таблиц. Если не получится - тогда tmpdir на RAM
...
Рейтинг: 0 / 0
Использование MySQL для хранилища данных
    #38541247
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Aleksandr KuzminskyKoukikey_buffer_size = 384M


Не используйте MyISAM.

Koukisort_buffer_size = 2M


OK

Koukiread_buffer_size = 2M


OK

Koukimax_heap_table_size = 1024M
tmp_table_size = 1024M


Аккуратно с этими буферами. Если MySQL начнет свопиться - все умрет. Я бы оставил их равными дефолту и пытался избавляться от временных таблиц. Если не получится - тогда tmpdir на RAM

ну неужели же я дожил до этого времени, когда хором люди в конфе по мусклю рекомендуют НЕ использовать ISAM ...

не просто реально счастье...
...
Рейтинг: 0 / 0
Использование MySQL для хранилища данных
    #38541255
Aleksandr Kuzminsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MasterZivну неужели же я дожил до этого времени, когда хором люди в конфе по мусклю рекомендуют НЕ использовать ISAM ...

не просто реально счастье...

А что, раньше рекомендовали?
Если есть InnoDB, то MyISAM использовать не вижу смысла. Ну ок, full text индексы до недавнего не поддерживались в InnoDB.
Кроме того, MyISAM не развивается как минимум лет пять.

Хорошо, что в 5.5 InnoDB по дефолту, раньше многие использовали MyISAM потому что это был дефолт
...
Рейтинг: 0 / 0
Использование MySQL для хранилища данных
    #38541314
Kouki
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Aleksandr Kuzminsky,
При выборе движка руководствовался статьями, где для средств аналитики советуют использовать MyISAM. Транзакционность и надежность мне не первостепенны, главное производительность. В современных условиях какой из движков наиболее оптимально использовать для построения хранилища данных: InnoDB, XtraDB, MyISAM, Aria?
...
Рейтинг: 0 / 0
Использование MySQL для хранилища данных
    #38541327
Aleksandr Kuzminsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
KoukiAleksandr Kuzminsky,
При выборе движка руководствовался статьями, где для средств аналитики советуют использовать MyISAM. Транзакционность и надежность мне не первостепенны, главное производительность. В современных условиях какой из движков наиболее оптимально использовать для построения хранилища данных: InnoDB, XtraDB, MyISAM, Aria?

С точки зрения производительности InnoDB лучше, чем MyISAM.
Почему? Потому что в InnoDB в памяти кешируются и данные и индексы (строго говоря, в InnoDB все является индексом), а в MyISAM - только индексы.

Допустим, если памяти много, больше, чем данных. Тогда с InnoDB чтения с диска не будет вообще, а запись будет последовательная и более-менее равномерная. Если же таблицы будут MyISAM, то Вы будете постоянно видеть чтение с диска и запись. Притом, IO будет преимущественно случайным, что есть плохо, если диски не SSD. (это не относится ко временным таблицам, это особый случай).

Поэтому, я бы советовал InnoDB или XtraDB (что есть тоже InnoDB + фичи).
...
Рейтинг: 0 / 0
Использование MySQL для хранилища данных
    #38541337
netwind
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Aleksandr KuzminskyMasterZivну неужели же я дожил до этого времени, когда хором люди в конфе по мусклю рекомендуют НЕ использовать ISAM ...

не просто реально счастье...

А что, раньше рекомендовали?

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

Если есть InnoDB, то MyISAM использовать не вижу смысла. Ну ок, full text индексы до недавнего не поддерживались в InnoDB.
Кроме того, MyISAM не развивается как минимум лет пять.

Хорошо, что в 5.5 InnoDB по дефолту, раньше многие использовали MyISAM потому что это был дефолт
Это просто потому что у вас клиенты такие. Так зачем вы обобщаете ?
...
Рейтинг: 0 / 0
Использование MySQL для хранилища данных
    #38541342
Kouki
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Aleksandr Kuzminsky,
Спасибо, попробую с InnoDB поближе поработать. Хотя insert был на 10-20% медленнее, когда я выбирал движки, select'ы правда не пробовал.
...
Рейтинг: 0 / 0
Использование MySQL для хранилища данных
    #38541349
netwind
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kouki. Хотя insert был на 10-20% медленнее, когда я выбирал движки, select'ы правда не пробовал.
Эа вы, что быть такого не может ! пацаны целую книжку про innodb написали !
Это, конечно, была ирония.
...
Рейтинг: 0 / 0
Использование MySQL для хранилища данных
    #38544300
Kouki
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Поставил MariaDB. XtraDB действительно шустрее мускульного MyISAM в 2-3 раза у меня читает, правда запись в 1,5-2 раза медленнее. Можно ли как-либо поднять скорость записи? Транзакционность, целостность и пр. не первостепенны, как я говорил выше.
Также решил попробовать для аналитики (мондриана) работать через представления:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
SELECT
  `p`.`TicketCode` AS `TicketCode`,
  `p`.`PaymentSum` AS `PaymentSum`,
  `p`.`AbonentID` AS `AbonentID`,
  `c`.`ContractorName` AS `ContractorName`,
  `d`.`Year` AS `DiscountYear`,
  `d`.`Quarter` AS `DiscountQuarter`,
  `d`.`Month` AS `DiscountMonth`,
  `d`.`MonthName` AS `DiscountMonthName`,
  `d`.`Day` AS `DiscountDay`,
  `d1`.`Year` AS `PaymentYear`,
  `d1`.`Quarter` AS `PaymentQuarter`,
  `d1`.`Month` AS `PaymentMonth`,
  `d1`.`MonthName` AS `PaymentMonthName`,
  `d2`.`Year` AS `Year`,
  `d2`.`Month` AS `Month`,
  `d2`.`MonthName` AS `MonthName`,
  `pm`.`PaymentMethodName` AS `PaymentMethodName`,
  `ps`.`PaymentSourceName` AS `PaymentSourceName`,
  `pt`.`PaymentTypeName` AS `PaymentTypeName`,
  `pu`.`PublicUtilitiesName` AS `PublicUtilitiesName`,
  `s`.`ServiceName` AS `ServiceName`,
  `s`.`ResourceName` AS `ResourceName`,
  `su`.`SubsidyName` AS `SubsidyName`
FROM ((((((((((`payment` `p`
  JOIN `contractor` `c`
    ON ((`p`.`ContractorID` = `c`.`ContractorID`)))
  JOIN `date` `d`
    ON ((`p`.`DateDiscountID` = `d`.`DateID`)))
  JOIN `date` `d1`
    ON ((`p`.`DatePaymentID` = `d1`.`DateID`)))
  JOIN `date` `d2`
    ON ((`p`.`DateID` = `d2`.`DateID`)))
  JOIN `paymentmethod` `pm`
    ON ((`p`.`PaymentMethodID` = `pm`.`PaymentMethodID`)))
  JOIN `paymentsource` `ps`
    ON ((`p`.`PaymentSourceID` = `ps`.`PaymentSourceID`)))
  JOIN `paymenttype` `pt`
    ON ((`p`.`PaymentTypeID` = `pt`.`PaymentTypeID`)))
  JOIN `publicutilities` `pu`
    ON ((`p`.`PublicUtilitiesID` = `pu`.`PublicUtilitiesID`)))
  JOIN `service` `s`
    ON ((`p`.`ServiceID` = `s`.`ServiceID`)))
  JOIN `subsidy` `su`
    ON ((`p`.`SubsidyID` = `su`.`SubsidyID`)))


Результат аналогичного запроса, приведенного в начале темы:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
select
    `Payment_All`.`ResourceName` as `c0`,
    `Payment_All`.`ServiceName` as `c1`,
    `Payment_All`.`PaymentSourceName` as `c2`,
    `Payment_All`.`DiscountYear` as `c3`,
    `Payment_All`.`DiscountQuarter` as `c4`,
    `Payment_All`.`DiscountMonth` as `c5`,
    `Payment_All`.`DiscountDay` as `c5`,
    sum(`Payment_All`.`PaymentSum`) as `m0`,
    count(distinct `Payment_All`.`TicketCode`) as `m1`
from
    `Payment_All` as `Payment_All`
where
    `Payment_All`.`DiscountYear` = 2013
and
    `Payment_All`.`DiscountQuarter` = 3
and
    `Payment_All`.`DiscountMonth` = 9
and 
    `Payment_All`.`ResourceName` in ('Водоотведение', 'Горячее водоснабжение', 'Холодное водоснабжение')
and
    `Payment_All`.`ServiceName` in ('Водоотведение', 'Горячая вода', 'Холодная вода')
group by
    `Payment_All`.`ResourceName`,
    `Payment_All`.`ServiceName`,
    `Payment_All`.`PaymentSourceName`,
    `Payment_All`.`DiscountYear`,
    `Payment_All`.`DiscountQuarter`,
    `Payment_All`.`DiscountMonth`,
    `Payment_All`.`DiscountDay`


авторCopying to tmp table on disk 2,594670 54,27
Sorting result 1,162951 24,32
Sending data 0,516080 10,79
Copying to tmp table 0,252053 5,27
statistics 0,178931 3,74
converting HEAP to Aria 0,073775 1,54
removing tmp table 0,000964 0,02
Opening tables 0,000530 0,01
end 0,000409 0,01
checking permissions 0,000215 0,00
starting 0,000119 0,00
updating status 0,000087 0,00
preparing 0,000079 0,00
optimizing 0,000065 0,00
closing tables 0,000021 0,00
cleaning up 0,000021 0,00
freeing items 0,000019 0,00
Table lock 0,000016 0,00
System lock 0,000014 0,00
init 0,000010 0,00
query end 0,000006 0,00
executing 0,000004 0,00

План:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
d	1	SIMPLE	index_merge	PRIMARY,IDX_Date_Month,IDX_Date_Quarter,IDX_Date_Year	IDX_Date_Year,IDX_Date_Month,IDX_Date_Quarter	2,1,1		7	Using intersect(IDX_Date_Year,IDX_Date_Month,IDX_Date_Quarter); Using where; Using temporary; Using filesort
p	1	SIMPLE	ref	IDX_Payment_ContractorID,IDX_Payment_DateDiscountID,IDX_Payment_DateID,IDX_Payment_DatePaymentID,IDX_Payment_PaymentMethodID,IDX_Payment_PaymentSourceID,IDX_Payment_PaymentTypeID,IDX_Payment_ServiceID,IDX_Payment_SubsidyID	IDX_Payment_DateDiscountID	4	abonentwh.d.DateID	5508	
pu	1	SIMPLE	eq_ref	PRIMARY	PRIMARY	1	abonentwh.p.PublicUtilitiesID	1	Using index
su	1	SIMPLE	eq_ref	PRIMARY	PRIMARY	1	abonentwh.p.SubsidyID	1	Using index
pm	1	SIMPLE	eq_ref	PRIMARY	PRIMARY	2	abonentwh.p.PaymentMethodID	1	Using index
s	1	SIMPLE	eq_ref	PRIMARY	PRIMARY	2	abonentwh.p.ServiceID	1	Using where
c	1	SIMPLE	eq_ref	PRIMARY	PRIMARY	2	abonentwh.p.ContractorID	1	Using index
ps	1	SIMPLE	eq_ref	PRIMARY	PRIMARY	2	abonentwh.p.PaymentSourceID	1	
d1	1	SIMPLE	eq_ref	PRIMARY	PRIMARY	4	abonentwh.p.DatePaymentID	1	Using index
d2	1	SIMPLE	eq_ref	PRIMARY	PRIMARY	4	abonentwh.p.DateID	1	Using index
pt	1	SIMPLE	eq_ref	PRIMARY	PRIMARY	1	abonentwh.p.PaymentTypeID	1	Using index
Применительна ли такая практика при работе с хранилищем? Пробовал разные запросы, результаты также различаются при использовании представлений или без них. Но в обоих случаях время копирования на диск временных таблиц около 50%, как с этим можно побороться? Только создать рамдиск?
...
Рейтинг: 0 / 0
Использование MySQL для хранилища данных
    #38544311
Aleksandr Kuzminsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Kouki Можно ли как-либо поднять скорость записи? Транзакционность, целостность и пр. не первостепенны, как я говорил выше.


Поставьте
innodb_flush_log_at_trx_commit=2

Если innodb_log_file_size равен дефолту (5М) - поменяйте на что-то около 256М.

Буфер пул побольше.

RAID контролеер с батарейкой и write-back cache policy.

SSD.

Как-то так.

Да, еще удалите индексы, которые не используются.
...
Рейтинг: 0 / 0
Использование MySQL для хранилища данных
    #38544314
netwind
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kouki, стандартные фокусы для иннодб включают в себя увеличение innodb_buffer_pool_size и innodb_flush_log_at_trx_commit=0.

Кроме того, то, что вам сейчас кажется, не обязательно кореллирует с теми результатами, которые вы бы получили при более строгом исследовании и длительных замерах. Данные в innodb занимают больше места, сам код сложнее. Иногда оно быстрее myisam, а иногда нет. Вот это вообще откровенная спекуляция фактами: "Почему? Потому что в InnoDB в памяти кешируются и данные и индексы (строго говоря, в InnoDB все является индексом), а в MyISAM - только индексы." . Кешируются данные myisam в памяти ОС. Кроме того, есть же специальная фича myisam_use_mmap. Не все так просто.

Понятно, почему Percona педалирует везде innodb - они работают с платежеспособным сегментом. Людьми, которым надо прямо сейчас решать проблемы роста в задачах с дикой конкуренцией . И за это они готовы отдавать 500$/час за консультацию и надежду.
Но большинство пользователей mysql не готовы или не считают нужным. Почему для них тоже педалируют innodb - мне не понятно.
Это мнение даже в книжке прослеживается. Как-то тупенько.
.
...
Рейтинг: 0 / 0
Использование MySQL для хранилища данных
    #38545326
Kouki
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Aleksandr Kuzminsky,
Сделал:
innodb-log-files-in-group = 4
innodb-log-file-size = 1G
innodb-flush-log-at-trx-commit = 2

При загрузке данных через ETL-приложение включаю set autocommit = 0, размер коммита там же 10000, данных 7 млн строк. Нагрузка на процессор во время загрузки ~20%, сильно нагружается фс. Что еще можно сделать (не аппаратно), что бы разгрузить фс и увеличить скорость вставки? В идеале хотелось бы вообще транзакции не использовать при вставке, но думаю с xtradb так не получится.
...
Рейтинг: 0 / 0
Использование MySQL для хранилища данных
    #38545507
Фотография ScareCrow
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Использование MySQL для хранилища данных
    #38545554
Aleksandr Kuzminsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
KoukiAleksandr Kuzminsky,
Сделал:
innodb-log-files-in-group = 4
innodb-log-file-size = 1G



Зачем такой большой лог?
Какой у Вас размер базы, буфер пула и сколько всего памяти на сервере?

Koukiinnodb-flush-log-at-trx-commit = 2

При загрузке данных через ETL-приложение включаю set autocommit = 0, размер коммита там же 10000, данных 7 млн строк. Нагрузка на процессор во время загрузки ~20%, сильно нагружается фс. Что еще можно сделать (не аппаратно), что бы разгрузить фс и увеличить скорость вставки? В идеале хотелось бы вообще транзакции не использовать при вставке, но думаю с xtradb так не получится.

А как диск загружен?
Сколько чтения, сколько записи? Запись случайная или последовательная?
...
Рейтинг: 0 / 0
Использование MySQL для хранилища данных
    #38545567
Kouki
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Aleksandr Kuzminsky,
4gb, innodb-buffer-pool-size = 2G
Как характер нагрузки посмотреть?
...
Рейтинг: 0 / 0
Использование MySQL для хранилища данных
    #38545571
Aleksandr Kuzminsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
KoukiAleksandr Kuzminsky,
4gb, innodb-buffer-pool-size = 2G


4 гигабайта - это всего памяти, я так понял? А размер базы какой?
Нет смысла делать такой большой лог. Если MySQL упадет, оно потом может очень долго делать crash recovery.
Сделайте два файла по 256G - будет более чем достаточно

KoukiКак характер нагрузки посмотреть?


iostat -dx 3

а лучше

pt-diskstats
...
Рейтинг: 0 / 0
Использование MySQL для хранилища данных
    #38545635
Kouki
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Aleksandr Kuzminsky,
Максимальный размер таблицы около 7Гб, общий размер бд около 11Гб.
В доках пишут, что большой размер логов увеличивает производительность, а скорость восстановления не принципиальна для меня.
Тестирую на обычной win7, диспетчер задач показывает 0 чтений, 12000 записей.
...
Рейтинг: 0 / 0
Использование MySQL для хранилища данных
    #38545650
Aleksandr Kuzminsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
KoukiМаксимальный размер таблицы около 7Гб, общий размер бд около 11Гб.


Докупите памяти. Честное слово, у меня на лептопе больше.

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


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

KoukiТестирую на обычной win7, диспетчер задач показывает 0 чтений, 12000 записей.

12000 записей в секунду? Не верю. Это монстр, а не диск. Вы бы не писали сюда о проблемах с производительностью :)
...
Рейтинг: 0 / 0
Использование MySQL для хранилища данных
    #38545975
Kouki
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Aleksandr Kuzminsky,
Не очень понял, если честно, что вы просили указать под "Сколько чтения, сколько записи? Запись случайная или последовательная?" и как это посмотрел в винде. ETL, через который я работаю, загружает данные порядка 5-9т записей в секунду.
А как правильно перенести логи на другой диск не подскажете? Пробовал задавать нужную папку в innodb_log_group_home_dir и переносил туда файлы ib_logfile, но сервер не стартовал после этого.
...
Рейтинг: 0 / 0
Использование MySQL для хранилища данных
    #38546187
Aleksandr Kuzminsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
KoukiAleksandr Kuzminsky,
Не очень понял, если честно, что вы просили указать под "Сколько чтения, сколько записи? Запись случайная или последовательная?" и как это посмотрел в винде. ETL, через который я работаю, загружает данные порядка 5-9т записей в секунду.


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

KoukiА как правильно перенести логи на другой диск не подскажете? Пробовал задавать нужную папку в innodb_log_group_home_dir и переносил туда файлы ib_logfile, но сервер не стартовал после этого.

Вроде бы, правильно. Может с разрешениями была проблема. Смотрите error log.
...
Рейтинг: 0 / 0
41 сообщений из 41, показаны все 2 страниц
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Использование MySQL для хранилища данных
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]