我有两张桌子。这些表的create命令如下
CREATE TABLE `invoice` (
`Id` bigint(20) NOT NULL,
`VersionNumber` int(11) NOT NULL,
`CreationDate` datetime default NULL,
`ModificationDate` datetime default NULL,
`CreateBy` bigint(20) default NULL,
`ModifyBy` bigint(20) default NULL,
`BusinessId` varchar(255) character set utf8 default NULL,
`Status` int(11) default NULL,
`VendorId` bigint(20) default NULL,
`CustomerId` bigint(20) default NULL,
`OrderDate` date default NULL,
`ExpectedDate` date default NULL,
`DeliveryDate` date default NULL,
`InvoiceFor` int(11) default NULL,
`Reference` varchar(255) character set utf8 default NULL,
`Agent` varchar(255) character set utf8 default NULL,
`BnAgent` varchar(255) character set utf8 default NULL,
`Note` varchar(255) character set utf8 default NULL,
`HasVoucher` char(1) character set utf8 default NULL,
PRIMARY KEY (`Id`),
KEY `CustomerId` (`CustomerId`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `invoiceitem` (
`Id` bigint(20) NOT NULL,
`VersionNumber` int(11) NOT NULL,
`CreationDate` datetime default NULL,
`ModificationDate` datetime default NULL,
`CreateBy` bigint(20) default NULL,
`ModifyBy` bigint(20) default NULL,
`BusinessId` varchar(255) default NULL,
`Status` int(11) default NULL,
`InvoiceId` bigint(20) default NULL,
`ProductId` bigint(20) default NULL,
`PackageQty` decimal(19,5) default NULL,
`PackagePrice` decimal(19,5) default NULL,
`ItemPerPackage` decimal(19,5) default NULL,
`ItemQty` decimal(19,5) default NULL,
`ItemPrice` decimal(19,5) default NULL,
`StoreQty` decimal(19,5) default NULL,
`RevenuePercent` decimal(19,5) default NULL,
`PurchasePrice` decimal(19,5) default NULL,
`Vat` decimal(19,5) default NULL,
`TotalAmount` decimal(19,5) default NULL,
`InvoiceItemFor` int(11) default NULL,
`LifeTimeUptoDate` datetime default NULL,
PRIMARY KEY (`Id`),
KEY `invoiceid_productid` (`InvoiceId`,`ProductId`),
KEY `ProductId` (`ProductId`),
CONSTRAINT `FK_invoiceitem` FOREIGN KEY (`InvoiceId`) REFERENCES `invoice` (`Id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
此查询的目的 我必须向管理员显示发票清单。他需要查看发票日期,发票编号,客户ID,产品ID以及客户是否先前使用该产品。
现在查询
SELECT iv.id, iv.CustomerId, ii.ProductId, MAX(iv2.orderdate) AS PriviousDate
FROM invoice AS iv
INNER JOIN invoice AS iv2
ON iv.CustomerId=iv2.CustomerId
AND iv.OrderDate>iv2.OrderDate
INNER JOIN invoiceItem AS ii
ON iv.id=ii.invoiceId
INNER JOIN invoiceItem AS ii2
ON iv2.id=ii2.invoiceId
AND ii.ProductId=ii2.ProductId
WHERE iv.Status=0
AND ii.Status=0
AND iv2.Status=0
AND ii2.Status=0
GROUP BY ii.ProductId, iv.CustomerId
这里iv.id和ii.id是主键 customerId和Productid字段也是索引 和invoiceId是foreginkey(iv.id = ii.invoiceId)
我在我的MySql服务器(本地)中运行此查询 但大部分时间我都超时了。我该如何优化此查询?
此查询的说明如下:
现在我申请
create index invoiceid_productid
on invoiceItem(invoiceId, productId)
之后解释结果是
答案 0 :(得分:0)
查看EXPLAIN
结果,问题显然是invoiceItem
表。它有200,000行,MySQL没有使用任何索引来访问它。
因此,您应该考虑创建索引以加快对它的访问。
我嘲笑你的桌子:
create table invoice (
id int auto_increment not null,
customerid int not null,
orderdate timestamp not null,
status int default 0 not null,
primary key(id)
);
create table invoiceItem (
id int auto_increment not null,
invoiceId int not null,
productId int not null,
status int default 0 not null,
primary key (id)
);
我创建了这些索引:
create index invoiceId on invoiceItem(invoiceId);
create index cod on invoice(customerid, orderdate);
create index stat on invoice(status);
My EXPLAIN(在空表上)现在所有表都使用类型ref
。
你也可以看到这个用于MySQL的tutorial; - )
答案 1 :(得分:0)
这里不多(看看你的索引是什么会有所帮助),但假设发票ID随发票日期而增加......我怀疑这可能会稍快一点:
SELECT iv.id, iv.CustomerId, ii.ProductId, MAX(iv2.orderdate) AS PriviousDate
FROM invoice AS iv
INNER JOIN invoice AS iv2
ON iv.CustomerId=iv2.CustomerId
AND iv.id>iv2.id
INNER JOIN invoiceItem AS ii
ON iv.id=ii.invoiceId
INNER JOIN invoiceItem AS ii2
ON iv2.id=ii2.invoiceId
AND ii.ProductId=ii2.ProductId
AND ii.invoiceId>ii2.invoiceId
WHERE iv.Status=0
AND ii.Status=0
AND iv2.Status=0
AND ii2.Status=0
GROUP BY ii.ProductId, iv.CustomerId
但是你确实需要在invoiceItem表中使用ProductId,Status和InvoiceId的索引,然后才能更快地发现它。