2

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                                  |
Ivan Bertola
  • 301
  • 1
  • 3
  • 12
  • While having a Fiddle is immensely helpful, please nevertheless add your main query (as code) to your question. This way it might still be helpful when the link (for whatever reason) is no longer active. – PM 77-1 Jul 12 '22 at 15:49
  • Please update your question with the EXPLAIN PLAN for when you query the view – NickW Jul 12 '22 at 15:58
  • @PM77-1 Thanks for the advice, I've edite the post by adding all the fiddle definitions and execution plan – Ivan Bertola Jul 12 '22 at 21:57
  • Do you have indexes for the JOIN-ed columns - e.g. for HEAD_ID? Also note that VIEWs can not have their own indexes. Also see https://stackoverflow.com/a/13945079/5962802 – IVO GELOV Jul 13 '22 at 08:10

0 Answers0