SQL - GROUP BY query optimization

Viewed 71

I am having some troubles trying to optimize the definition of a view in my db.

The query sums 2 kind of quantities based on LEFT JOIN of 3 tables, described as the stocking view within this fiddle: SQL Fiddle

Basically I tried to create indexes or re-define the view, but every time the execution time is ~5.5s even if the larges of the tables - the rows table in the fiddle - has ~15K records.

The thing that I'm struggling to understand is why, even if an index is defined for the GROUP BY column statement - shown in the possible_keys result for the EXPLAIN command - no index is used.

--- EDIT ---

I think that I've found my issue, the use of LEFT JOIN instead of INNER JOIN on the head table and the rows table was slowing the query down due to MySQL internal design Also usign a coverage index on the head table for ID and CLOSING_DATE better tune up the performaces

DDLs AND RECORDS

CREATE TABLE head (
  ID varchar(30) NOT NULL,
  CLOSING_DATE int NOT NULL,
  PRIMARY KEY(ID),
  KEY CLOSING (ID, CLOSING_DATE)
);

CREATE TABLE `rows` (
  ID int NOT NULL,
  HEAD_ID varchar(30) NOT NULL,
  PRODUCT varchar(30) NOT NULL,
  QTY decimal(16,6) NOT NULL,
  STKQTY decimal(16,6) NOT NULL,
  PRIMARY KEY(ID),
  KEY PROD(PRODUCT),
  KEY HEAD(HEAD_ID)
);

CREATE TABLE production (
  ID int NOT NULL,
  ROW_ID int NOT NULL,
  QTY decimal(16,6) NOT NULL,
  PRIMARY KEY(ID),
  KEY ROWID(ROW_ID)
);

CREATE VIEW row_prod AS(
  SELECT ROW_ID, SUM(QTY) AS PRD_QTY FROM production WHERE ROW_ID <> 0 GROUP BY ROW_ID
);

CREATE VIEW stocking AS(
  SELECT 
    `rows`.PRODUCT,
    SUM(`rows`.STKQTY) AS STKQTY,
    GREATEST(SUM(CASE WHEN CLOSING_DATE <> 0 THEN 0 ELSE (`rows`.QTY - `rows`.STKQTY - COALESCE(row_prod.PRD_QTY, 0)) END), 0) AS RESQTY
  FROM
    `rows`
  INNER JOIN
    head ON head.ID = `rows`.HEAD_ID
  LEFT JOIN
    row_prod ON row_prod.ROW_ID = `rows`.ID
  GROUP BY
    `rows`.PRODUCT
);

INSERT INTO head (ID, CLOSING_DATE) VALUES 
 (1, 0),
 (2, 20220601),
 (3, 0);

INSERT INTO `rows` (ID, HEAD_ID, PRODUCT, QTY, STKQTY) VALUES 
 (1, 1, 'PROD_A', 10, 2),
 (2, 1, 'PROD_B',  5, 0),
 (3, 2, 'PROD_A', 15, 6),
 (4, 2, 'PROD_D',  7, 0),
 (5, 2, 'PROD_E', 12, 4),
 (6, 3, 'PROD_A',  3, 0),
 (7, 3, 'PROD_B',  1, 1),
 (8, 3, 'PROD_F',  5, 5),
 (9, 3, 'PROD_G',  6, 6);

INSERT INTO production (ID, ROW_ID, QTY) VALUES 
 (1, 1, 1),
 (2, 3, 6),
 (3, 4, 10);

EXPLAIN DETAILS

id|select_type|table     |partitions|type   |possible_keys   |key     |key_len|ref            |rows|filtered|Extra                                        |
--+-----------+----------+----------+-------+----------------+--------+-------+---------------+----+--------+---------------------------------------------+
 1|PRIMARY    |<derived2>|          |ALL    |                |        |       |               |   6|   100.0|                                             |
 2|DERIVED    |head      |          |index  |PRIMARY,CLOSING |CLOSING |96     |rows.HEAD_ID   |   3|   100.0|Using index; Using temporary; Using filesort |
 2|DERIVED    |rows      |          |ref    |HEAD,PROD       |HEAD    |92     |head.ID        |   1|   100.0|                                             |
 2|DERIVED    |<derived3>|          |ref    |                |        |4      |rows.ID        |   2|   100.0|                                             |
 3|DERIVED    |production|          |index  |ROWID           |ROWID   |4      |               |   3|   100.0|Using where                                  |
0 Answers
Related