简体   繁体   中英

Indexing in Mysql on multiple tables

I have 4 Tables, Transaction table, customer table, products table & Plant Table.

I'm querying daily sale group by product table Item Type, and, also customer-wise sale on daily basis.

But these queries execution time is very high (My tran table is about 2M rows only)

How could I improve the performance of my DB?

I created my Tables as follows :

 Transaction Table : CREATE TABLE `tran` ( `Plant` CHAR(4) NOT NULL COLLATE 'utf8_bin', `tdate` DATE NOT NULL, `InvNo` VARCHAR(10) NULL DEFAULT NULL COLLATE 'utf8_bin', `Customer` CHAR(8) NOT NULL COLLATE 'utf8_bin', `ICode` CHAR(8) NOT NULL COLLATE 'utf8_bin', `RQty` FLOAT(10,2) NULL DEFAULT NULL, `FQty` FLOAT(10,2) NULL DEFAULT NULL, `RAmt` FLOAT(10,2) NULL DEFAULT NULL, `TaxAmt` FLOAT(10,2) NULL DEFAULT NULL, `TQty` FLOAT(10,2) NULL DEFAULT NULL, `TAmt` FLOAT(10,2) NULL DEFAULT NULL ) COLLATE='utf8_bin' ENGINE=InnoDB ROW_FORMAT=COMPACT ; Customer Details Table : CREATE TABLE `cust` ( `slno` SMALLINT(6) NULL DEFAULT NULL, `AArea` CHAR(2) NULL DEFAULT NULL, `Plant` CHAR(4) NULL DEFAULT NULL, `Customer` CHAR(8) NOT NULL COLLATE 'utf8_bin', `cName` VARCHAR(50) NULL DEFAULT NULL, `DOC` DATE NULL DEFAULT NULL, `L1` VARCHAR(25) NULL DEFAULT NULL, `L2` VARCHAR(25) NULL DEFAULT NULL, `L3` VARCHAR(35) NULL DEFAULT NULL, `SE` CHAR(6) NULL DEFAULT NULL, `SEName` VARCHAR(35) NULL DEFAULT NULL ) COLLATE='utf8_general_ci' ENGINE=InnoDB ROW_FORMAT=COMPACT ; Products/Materials Table : CREATE TABLE `prod` ( `Slno` INT(3) NULL DEFAULT NULL, `ICode` CHAR(8) NOT NULL, `IGroup` CHAR(8) NULL DEFAULT NULL, `IName` CHAR(50) NULL DEFAULT NULL, `CAT` CHAR(5) NULL DEFAULT NULL, `IType` CHAR(20) NULL DEFAULT NULL, `SubType` CHAR(30) NULL DEFAULT NULL, `Norm` CHAR(20) NULL DEFAULT NULL, `SKU` CHAR(20) NULL DEFAULT NULL, `ICat` CHAR(30) NULL DEFAULT NULL, PRIMARY KEY (`ICode`) ) COLLATE='utf8_general_ci' ENGINE=InnoDB ROW_FORMAT=COMPACT ; Plant Table : CREATE TABLE `plant` ( `AArea` INT(1) NULL DEFAULT NULL, `AName` CHAR(50) NULL DEFAULT NULL, `MainPlant` CHAR(4) NULL DEFAULT NULL, `Plant` CHAR(4) NULL DEFAULT NULL, `PName` CHAR(50) NULL DEFAULT NULL, `ShortName` CHAR(50) NULL DEFAULT NULL ) COLLATE='utf8_general_ci' ENGINE=InnoDB ; Select query : select pc.mainplant,p.cat,p.itype, sum(if(year(tdate)=2015,tqty,0)) as _2015, sum(if(year(tdate)=2016,tqty,0)) as _2016 from tran z left join plant pc on pc.Plant=z.Plant left join prod p on p.ICode=z.Icode left join cust c on c.Customer=z.Customer where pc.mainplant = 'xxxx' group by pc.mainplant,p.cat,p.itype; 

  • Use VARCHAR instead of CHAR unless the string is truly fixed width.
  • Never use FLOAT(m,n) , either use FLOAT for "scientific" quantities or DECIMAL(m,n) for exact quantities, such as money.
  • Have a PRIMARY KEY on every table, preferably using some 'natural' PK as a column (or combination of columns) that is unique.
  • Do not say LEFT unless the right-hand table is truly optional.

The first step in speeding up that query is

INDEX(mainplant)

Make the rest of the changes I suggested, then we can make another pass at optimizing the query. (The performance issue may be solved by adding this index, plus the PKs.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM