Каков наилучший способ создания отчетов MySQL в огромных базах данных?

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

База данных имеет более 1,5 млн строк для каждой из четырех таблиц.
два для заголовков и другой для деталей.

Я создаю отчеты, объединяя заголовки с деталями и некоторые другие таблицы, чтобы получить полную информацию для представления.

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

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

Я искал в Google и нашел несколько идей о секционировании таблиц и других об архивировании, изменении всего движка или даже обновлении требований к серверу.

Отношение между двумя таблицами (invoice_header и invoice_detail) таково (один ко многим), что invoice_header является заголовком счета-фактуры только с итогами. Который связан с invoice_detail, используя идентификатор местоположения (loc_id) и номер счета-фактуры (invo_no), так как каждое местоположение имеет свой серийный номер. Деталь счета-фактуры содержит детали каждого счета-фактуры.

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

Запрос занимает слишком много (15 — 20) секунд для получения

-Всего строк: 1495873

-Всего выбранных строк: 9 — 12

SELECT SUM(invoice_detail.qty) AS qty, Month(invoice_header.date) AS month
FROM invoice_detail
JOIN invoice_header ON invoice_detail.invo_no = invoice_header.invo_no
AND  invoice_detail.loc_id = invoice_header.loc_id
WHERE invoice_detail.item_id = {$itemId}
GROUP BY Month(invoice_header.date)
ORDER BY Month(invoice_header.date)

EXPLAIN:

объяснять

Структура таблицы invoice_header:

CREATE TABLE `invoice_header` (
`invo_type` varchar(1) NOT NULL,
`invo_no` int(20) NOT NULL AUTO_INCREMENT,
`invo_code` varchar(50) NOT NULL,
`date` date NOT NULL,
`time` time NOT NULL,
`cust_id` int(11) NOT NULL,
`loc_id` int(3) NOT NULL,
`cash_man_id` int(11) NOT NULL,
`sales_man_id` int(11) NOT NULL,
`ref_invo_no` int(20) NOT NULL,
`total_amount` decimal(19,2) NOT NULL,
`tax` decimal(19,2) NOT NULL,
`discount_amount` decimal(19,2) NOT NULL,
`net_value` decimal(19,2) NOT NULL,
`split` decimal(19,2) NOT NULL,
`qty` int(11) NOT NULL,
`payment_type_id` varchar(20) NOT NULL,
`comments` varchar(255) NOT NULL,
PRIMARY KEY (`invo_no`,`loc_id`)
) ENGINE=InnoDB AUTO_INCREMENT=20286 DEFAULT CHARSET=utf8

Структура таблицы invoice_header:

Структура таблицы invoice_detail:

CREATE TABLE `invoice_detail` (
`invo_no` int(11) NOT NULL,
`loc_id` int(3) NOT NULL,
`serial` int(11) NOT NULL,
`item_id` varchar(11) NOT NULL,
`size_id` int(5) NOT NULL,
`qty` int(11) NOT NULL,
`rtp` decimal(19,2) NOT NULL,
`type` tinyint(1) NOT NULL,
PRIMARY KEY (`invo_no`,`loc_id`,`serial`),
KEY `item_id` (`item_id`),
KEY `size_id` (`size_id`),
KEY `invo_no` (`invo_no`),
KEY `serial` (`serial`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

Структура таблицы invoice_detail:

После добавления «Извлечь»:

EXPLAIN SELECT SUM( invoice_detail.qty ) AS qty, Month( invoice_header.date ) AS
MONTH
FROM invoice_detail
JOIN invoice_header ON invoice_detail.invo_no = invoice_header.invo_no
AND invoice_detail.loc_id = invoice_header.loc_id
WHERE invoice_detail.item_id =11321
GROUP BY EXTRACT(
YEAR_MONTH FROM invoice_header.date )

После добавления & quot; Извлечь & quot;

Я использую неплохой выделенный сервер с:

Intel Xeon Quad Core 3.3GHz (8 threads)
1 Gbps Uplink
16 GB RAM
1,000 GB RAID-1 Drives
25 TB Bandwidth

Какие-либо предложения?

1

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]