2017-04-07 80 views
0

索引在MySQL上的多個表

我有4個表,交易表,客戶表,產品表&植物表。

我在按產品表項目類型查詢每日銷售組,並按客戶要求每日銷售。

但這些查詢執行時間是非常高的(我TRAN表僅約2M行)

我怎麼能提高我的DB的性能?

我創造了我的表如下:

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;

+1

更新你的問題並添加你想要改進的選項.. – scaisEdge

回答

0
  • 使用VARCHAR而不是CHAR除非字符串是真正的固定寬度。
  • 千萬不要使用FLOAT(m,n),要麼使用FLOAT作爲「科學」數量,要麼使用DECIMAL(m,n)以確定數量,例如金錢。
  • 在每個表上都有一個PRIMARY KEY,最好使用一些「自然」PK作爲唯一的列(或列的組合)。
  • 不要說LEFT除非右手錶是真正可選的。

在加快該查詢的第一步是

INDEX(mainplant) 

使我的建議,那麼我們就可以在優化查詢再拍通其餘的改動。 (性能問題可能可以通過加上這個索引加上PK來解決。)