提高mysql查询速度
我有一个mysql查询来连接四个表,我认为最好是连接表,但现在mysql数据越来越大,查询似乎会导致应用程序停止执行提高mysql查询速度,mysql,performance,Mysql,Performance,我有一个mysql查询来连接四个表,我认为最好是连接表,但现在mysql数据越来越大,查询似乎会导致应用程序停止执行 SELECT `purchase_order`.`id`, `purchase_order`.`po_date` AS po_date, `purchase_order`.`po_number`,
SELECT
`purchase_order`.`id`,
`purchase_order`.`po_date` AS po_date,
`purchase_order`.`po_number`,
`purchase_order`.`customer_id` AS customer_id ,
`customer`.`name` AS customer_name,
`purchase_order`.`status` AS po_status,
`purchase_order_items`.`product_id`,
`purchase_order_items`.`po_item_name`,
`product`.`weight` as product_weight,
`product`.`pending` as product_pending,
`product`.`company_owner` as company_owner,
`purchase_order_items`.`uom`,
`purchase_order_items`.`po_item_type`,
`purchase_order_items`.`order_sequence`,
`purchase_order_items`.`pending_balance`,
`purchase_order_items`.`quantity`,
`purchase_order_items`.`notes`,
`purchase_order_items`.`status` AS po_item_status,
`purchase_order_items`.`id` AS po_item_id
FROM `purchase_order`
INNER JOIN customer ON `customer`.`id` = `purchase_order`.`customer_id`
INNER JOIN purchase_order_items ON `purchase_order_items`.`po_id` = `purchase_order`.`id`
INNER JOIN product ON `purchase_order_items`.`product_id` = `product`.`id`
GROUP BY id ORDER BY `purchase_order`.`po_date` DESC LIMIT 0, 20
我的问题实际上是需要很多时间才能完成的查询。有没有办法加快此查询或更改此查询以更快地检索数据
以下是评论中要求的解释。
提前谢谢,我真的希望这是我问的正确渠道。如果没有,请告诉我 您需要确保
purchase\u order.po\u date
和所有id列都已编制索引。您可以使用下面的查询进行检查
SHOW INDEX FROM yourtable;
您需要确保
purchase\u order.po\u date
和所有id列都已编制索引。您可以使用下面的查询进行检查
SHOW INDEX FROM yourtable;
因为你提到数据越来越大了。我建议进行切分,然后您可以并行化多个查询。请参阅以下文章
因为您提到数据越来越大。我建议进行切分,然后您可以并行化多个查询。请参阅以下文章
首先,我稍微提高了可读性。您不需要在每个表的周围打勾。列引用。此外,简而言之,使用别名效果很好。例如:“po”代替“采购订单”,“poi”代替“采购订单项目”。我唯一一次使用记号是在可能导致问题的保留字周围 其次,在查询中没有任何聚合(sum、min、max、count、avg等),因此您应该能够剥离GROUPBY子句 至于索引,我必须假设您在引用表的各自“id”键列上有一个索引 对于您的采购订单表,如果您已经有一个索引使用它,我会在第一个索引字段位置有一个基于“采购订单日期”的索引。因为您的orderby在上面,所以让引擎首先直接跳转到那些有日期的记录,然后您就可以解析降序了
SELECT
po.id,
po.po_date,
po.po_number,
po.customer_id,
c.`name` AS customer_name,
po.`status` AS po_status,
poi.product_id,
poi.po_item_name,
p.weight as product_weight,
p.pending as product_pending,
p.company_owner,
poi.uom,
poi.po_item_type,
poi.order_sequence,
poi.pending_balance,
poi.quantity,
poi.notes,
poi.`status` AS po_item_status,
poi.id AS po_item_id
FROM
purchase_order po
INNER JOIN customer c
ON po.customer_id = c.id
INNER JOIN purchase_order_items poi
ON po.id = poi.po_id
INNER JOIN product p
ON poi.product_id = p.id
ORDER BY
po.po_date DESC
LIMIT
0, 20
首先,我稍微提高了可读性。您不需要在每个表的周围打勾。列引用。此外,简而言之,使用别名效果很好。例如:“po”代替“采购订单”,“poi”代替“采购订单项目”。我唯一一次使用记号是在可能导致问题的保留字周围 其次,在查询中没有任何聚合(sum、min、max、count、avg等),因此您应该能够剥离GROUPBY子句 至于索引,我必须假设您在引用表的各自“id”键列上有一个索引 对于您的采购订单表,如果您已经有一个索引使用它,我会在第一个索引字段位置有一个基于“采购订单日期”的索引。因为您的orderby在上面,所以让引擎首先直接跳转到那些有日期的记录,然后您就可以解析降序了
SELECT
po.id,
po.po_date,
po.po_number,
po.customer_id,
c.`name` AS customer_name,
po.`status` AS po_status,
poi.product_id,
poi.po_item_name,
p.weight as product_weight,
p.pending as product_pending,
p.company_owner,
poi.uom,
poi.po_item_type,
poi.order_sequence,
poi.pending_balance,
poi.quantity,
poi.notes,
poi.`status` AS po_item_status,
poi.id AS po_item_id
FROM
purchase_order po
INNER JOIN customer c
ON po.customer_id = c.id
INNER JOIN purchase_order_items poi
ON po.id = poi.po_id
INNER JOIN product p
ON poi.product_id = p.id
ORDER BY
po.po_date DESC
LIMIT
0, 20
这会给你正确的ID列表吗
SELECT id
FROM purchase_order
ORDER BY`po_date` DESC
LIMIT 0, 20
如果是这样,那么在启动到连接之前,先从该代码开始。您还可以(我认为)去掉导致行“爆炸-内爆”的groupby
像这样的
SELECT
`purchase_order`.`id`,
`purchase_order`.`po_date` AS po_date,
`purchase_order`.`po_number`,
`purchase_order`.`customer_id` AS customer_id ,
`customer`.`name` AS customer_name,
`purchase_order`.`status` AS po_status,
`purchase_order_items`.`product_id`,
`purchase_order_items`.`po_item_name`,
`product`.`weight` as product_weight,
`product`.`pending` as product_pending,
`product`.`company_owner` as company_owner,
`purchase_order_items`.`uom`,
`purchase_order_items`.`po_item_type`,
`purchase_order_items`.`order_sequence`,
`purchase_order_items`.`pending_balance`,
`purchase_order_items`.`quantity`,
`purchase_order_items`.`notes`,
`purchase_order_items`.`status` AS po_item_status,
`purchase_order_items`.`id` AS po_item_id
FROM (SELECT id, po_date, po_number, customer_id, status
FROM purchase_order
ORDER BY `po_date` DESC
LIMIT 0, 5) as purchase_order
INNER JOIN customer ON `customer`.`id` = `purchase_order`.`customer_id`
INNER JOIN purchase_order_items
ON `purchase_order_items`.`po_id` = `purchase_order`.`id`
INNER JOIN product ON `purchase_order_items`.`product_id` = `product`.`id`
GROUP BY purchase_order.id DESC
LIMIT 0, 5
这会给你正确的ID列表吗
SELECT id
FROM purchase_order
ORDER BY`po_date` DESC
LIMIT 0, 20
如果是这样,那么在启动到连接之前,先从该代码开始。您还可以(我认为)去掉导致行“爆炸-内爆”的groupby
像这样的
SELECT
`purchase_order`.`id`,
`purchase_order`.`po_date` AS po_date,
`purchase_order`.`po_number`,
`purchase_order`.`customer_id` AS customer_id ,
`customer`.`name` AS customer_name,
`purchase_order`.`status` AS po_status,
`purchase_order_items`.`product_id`,
`purchase_order_items`.`po_item_name`,
`product`.`weight` as product_weight,
`product`.`pending` as product_pending,
`product`.`company_owner` as company_owner,
`purchase_order_items`.`uom`,
`purchase_order_items`.`po_item_type`,
`purchase_order_items`.`order_sequence`,
`purchase_order_items`.`pending_balance`,
`purchase_order_items`.`quantity`,
`purchase_order_items`.`notes`,
`purchase_order_items`.`status` AS po_item_status,
`purchase_order_items`.`id` AS po_item_id
FROM (SELECT id, po_date, po_number, customer_id, status
FROM purchase_order
ORDER BY `po_date` DESC
LIMIT 0, 5) as purchase_order
INNER JOIN customer ON `customer`.`id` = `purchase_order`.`customer_id`
INNER JOIN purchase_order_items
ON `purchase_order_items`.`po_id` = `purchase_order`.`id`
INNER JOIN product ON `purchase_order_items`.`product_id` = `product`.`id`
GROUP BY purchase_order.id DESC
LIMIT 0, 5
请分享Explain Extended
的结果。还可以共享表上的索引详细信息。是否有正确索引的表?@MadhurBhaiya我不确定要给出什么,但会先尝试搜索。@JigneshM.Khatri我不确定列的正确索引是什么。将搜索它。您需要索引在联接表和where
子句中经常使用的所有列。请共享Explain Extended
的结果。还可以共享表上的索引详细信息。是否有正确索引的表?@MadhurBhaiya我不确定要给出什么,但会先尝试搜索。@JigneshM.Khatri我不确定列的正确索引是什么。将搜索它。您需要索引在联接表和where
子句中经常使用的所有列。谢谢您的建议。好的,谢谢你的建议。现在就可以了。我添加了group by id,因为我得到了基于id的重复结果,我认为这是重复的。我添加group by id,因为我得到了基于id的重复结果,我认为这是重复的。非常感谢,这比我的查询快了大约20到30倍,但我仍然需要更改查询,因为我对该限制提出了质疑,因为它给了我比我预期的更多的限制。limit
位于派生表(子查询)中。或者,在联接之后,您是否会得到更多的行?如果是这样的话,您可能确实需要外部的限制。在这种情况下,ORDER BY
是否需要另一列使其具有确定性?是的,我在连接后获得了更多的行,但没有连接正确的行数是正确的,但当我添加连接时,它超出了预期。请尝试您的建议。:)它不起作用。因为如果我添加限制,它会复制ID。非常感谢,这比我的查询快了20到30倍,但我仍然需要更改查询,因为我对限制有疑问,因为它给了我比我预期的更多的信息。限制
在派生表(子查询)中。或者,在联接之后,您是否会得到更多的行?如果是这样的话,您可能确实需要外部的限制。在这种情况下,orderby
是否需要另一列使其具有确定性?是的,我在连接后获得了更多的行,但是没有连接,正确的行数是正确的,但是当我添加连接时,它变为