简体   繁体   English

更好的MySQL查询性能

[英]Better MySQL Query Performance

I want to get the SUM of QTYs of an item# grouped be months, the query takes too long (15 - 20) seconds to fetch. 我希望得到一个项目#QTYs的SUM分组为几个月,查询需要太长时间(15 - 20)秒才能获取。

-Total rows: 1495873 -Total Fetched rows: 9 - 12 -Total rows:1495873 -Total Fetched rows:9 - 12

The relation between two tables ( invoice_header and invoice_detail ) is (one to many) that the invoice_header is the header of an invoice, with only totals. 两个表( invoice_headerinvoice_detail )之间的关系是(一对多), invoice_header是发票的标题,只有总计。 Which is linked to invoice_detail using location ID ( loc_id ) and Invoice number ( invo_no ), as each location has its own serial number. 使用位置ID( loc_id )和发票编号( invo_no )链接到invoice_detail,因为每个位置都有自己的序列号。 The invoice detail contains the details of each invoice. 发票明细包含每张发票的详细信息。

Is there's a better way to enhance the performance of that query, here it's: 有没有更好的方法来增强该查询的性能,这里是:

SELECT SUM(invoice_detail.qty) AS qty, Month(invoice_header.date) AS month
FROM invoice_detail
JOIN invoice_header ON invoice_detail.invo_no = invoice_header.invo_no
AND  invoice_detail.loc_id = invoice_header.loc_id
WHERE invoice_detail.item_id = {$itemId}
GROUP BY Month(invoice_header.date)
ORDER BY Month(invoice_header.date)

EXPLAIN: 说明:

说明

invoice_header table structure: invoice_header表结构:

CREATE TABLE `invoice_header` (
 `invo_type` varchar(1) NOT NULL,
 `invo_no` int(20) NOT NULL AUTO_INCREMENT,
 `invo_code` varchar(50) NOT NULL,
 `date` date NOT NULL,
 `time` time NOT NULL,
 `cust_id` int(11) NOT NULL,
 `loc_id` int(3) NOT NULL,
 `cash_man_id` int(11) NOT NULL,
 `sales_man_id` int(11) NOT NULL,
 `ref_invo_no` int(20) NOT NULL,
 `total_amount` decimal(19,2) NOT NULL,
 `tax` decimal(19,2) NOT NULL,
 `discount_amount` decimal(19,2) NOT NULL,
 `net_value` decimal(19,2) NOT NULL,
 `split` decimal(19,2) NOT NULL,
 `qty` int(11) NOT NULL,
 `payment_type_id` varchar(20) NOT NULL,
 `comments` varchar(255) NOT NULL,
 PRIMARY KEY (`invo_no`,`loc_id`)
) ENGINE=InnoDB AUTO_INCREMENT=20286 DEFAULT CHARSET=utf8

invoice_header表结构:

invoice_detail table structure: invoice_detail表结构:

CREATE TABLE `invoice_detail` (
 `invo_no` int(11) NOT NULL,
 `loc_id` int(3) NOT NULL,
 `serial` int(11) NOT NULL,
 `item_id` varchar(11) NOT NULL,
 `size_id` int(5) NOT NULL,
 `qty` int(11) NOT NULL,
 `rtp` decimal(19,2) NOT NULL,
 `type` tinyint(1) NOT NULL,
 PRIMARY KEY (`invo_no`,`loc_id`,`serial`),
 KEY `item_id` (`item_id`),
 KEY `size_id` (`size_id`),
 KEY `invo_no` (`invo_no`),
 KEY `serial` (`serial`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

invoice_detail表结构:

According to see the result of explain invoice_header can not use any multiple index. 根据查看结果说明invoice_header不能使用任何多个索引。

You could create index on field invo_no on invoice_header Table. 您可以在invoice_header表上的字段invo_no上创建索引。

How long does it take by following SQL? 遵循SQL需要多长时间?

SELECT count(*)
FROM invoice_detail
WHERE invoice_detail.item_id = {$itemId}

If this SQL takes 15-20 seconds, you should add an index on field item_id on inovice_detail table. 如果此SQL需要15-20秒,则应在inovice_detail表的字段item_id上添加索引。

The invoice_header already had the primary key on the join columns of invo_no and loc_id, so you don't need add other indexes on invoice_header table. invoice_header已在invo_no和loc_id的连接列上拥有主键,因此您无需在invoice_header表上添加其他索引。 But if you add an index on fields invo_no, loc_id and date, that may enhance a little performance by only index scan. 但是如果你在字段invo_no,loc_id和date上添加一个索引,那么只能通过索引扫描来增强一点性能。

Try creating a few indexes on some columns: invo_no, loc_id, item_id, date. 尝试在某些列上创建一些索引:invo_no,loc_id,item_id,date。

based on your explain, your query is scanning all rows in invoice_header. 根据您的解释,您的查询正在扫描invoice_header中的所有行。 Index the columns that make the join... invo_no, loc_id 索引进行连接的列... invo_no,loc_id

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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