Расчет суммы трех разностей в трех таблицах - PullRequest
0 голосов
/ 26 мая 2019

У меня есть эти таблицы:

DROP TABLE IF EXISTS books;
CREATE TABLE `books` (
  `bookId` mediumint(8) UNSIGNED NOT NULL,
  `title` varchar(10) NOT NULL,
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

ALTER TABLE `books`
  ADD PRIMARY KEY (`bookId`),

DROP TABLE IF EXISTS movements;
CREATE TABLE `movements` (
  `movementId` mediumint(8) UNSIGNED NOT NULL,
  `movementTypeId` tinyint(3) UNSIGNED NOT NULL,
  `deletedFlag` tinyint(3) UNSIGNED NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

ALTER TABLE `movements`
  ADD PRIMARY KEY (`movementId`),
  ADD KEY `movementId` (`movementTypeId`,`deletedFlag`) USING BTREE;

DROP TABLE IF EXISTS movements_types;
CREATE TABLE `movements_types` (
  `movementTypeId` mediumint(8) UNSIGNED NOT NULL,
  `title` varchar(200) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

ALTER TABLE `movements_types`
  ADD PRIMARY KEY (`movementTypeId`);

DROP TABLE IF EXISTS movements_books;
CREATE TABLE `movements_books` (
  `movementId` mediumint(8) UNSIGNED NOT NULL,
  `bookId` mediumint(8) UNSIGNED NOT NULL,
  `bookSize` tinyint(3) UNSIGNED NOT NULL,
  `quantity` smallint(5) UNSIGNED NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `books` (`bookId`, `title`) VALUES
(1, 'Harry Potter'),
(2, 'Mysql Join'),
(3, 'Comedy');

INSERT INTO `movements` (`movementId`, `movementTypeId`, `deletedFlag`) VALUES
(7, 1, 0),
(8, 2, 0),
(9, 2, 0);

INSERT INTO `movements_types` (`movementTypeId`, `title`) VALUES
(1, "Bought"),
(2, "Sold");

INSERT INTO `movements_books` (`movementId`, `bookId`, `bookSize`, `quantity`) VALUES
(7, 1, 1, 3),
(7, 1, 2, 3),
(7, 2, 1, 3),
(7, 2, 2, 3),
(8, 1, 1, 2),
(8, 1, 1, 2),
(9, 2, 1, 3);

bookSize - это просто целое число, указывающее размер книги.

движения_буксов на самом деле имеет 111824 записей, движений - 4534. Удаленный флаг равен 1 дляудаленное движение (я предпочитаю держать их помеченными) и 0 в противном случае.

Мне нужна помощь в создании индексов, и мне нужны следующие результаты:

1) размеры проданы / куплены / доступны для каждой книги (bookId, книгаРазмер, книгиПродано, книгиКупили, книгиКупили минус книгиПродано)

2) книги проданы / куплены / доступны для каждой книги любого размера (идентификатор книги, КнигиПроданы, книгиКупили, книгиКупили минус книгиПродано)

Получитьстатистику, которую я пробовал:

SELECT 
   books.title
   movements_books_grouped.bookId,
   SUM(IF(movements.movementTypeId=1, movements_books_grouped.quantity, NULL)) AS booksBought,
   SUM(IF(movements.movementTypeId=2, movements_books_grouped.quantity, NULL)) AS booksSold,
   (
       SUM(IF(movements.movementTypeId=1, movements_books_grouped.quantity, 0))- 
       SUM(IF(movements.movementTypeId=2, movements_books_grouped.quantity, 0)) 
   ) AS booksAvailability,
   FROM 
   (
   SELECT bookId,quantity,movementId FROM movements_books GROUP BY bookId
   ) AS movements_books_grouped 
   JOIN movements ON movements.movementId=movements_books_grouped.movementId
   JOIN books ON books.bookId=movements_books_grouped.bookId
   GROUP BY movements_books_grouped.bookId
   ORDER BY book.title

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

1 Ответ

0 голосов
/ 26 мая 2019

Вот запрос, который может использовать индексы:

SELECT m.movementId
     , m.movementTypeId
     , m.deletedFlag
     , mb.bookId
     , mb.bookSize
     , t.title
  FROM movements m
  JOIN movements_types t 
    ON t.movementTypeId = m.movementTypeId
  JOIN movements_books mb
    ON mb.movementid = m.movementid
 WHERE m.deletedFlag=0;

Индекс (m.movementTypeId, m.deletedFlag) может оказаться полезным, но лучше пососать его и посмотреть.

...