提高mysql查询速度

提高mysql查询速度,mysql,performance,Mysql,Performance,我有一个mysql查询来连接四个表,我认为最好是连接表,但现在mysql数据越来越大,查询似乎会导致应用程序停止执行 SELECT `purchase_order`.`id`, `purchase_order`.`po_date` AS po_date, `purchase_order`.`po_number`,

我有一个mysql查询来连接四个表,我认为最好是连接表,但现在mysql数据越来越大,查询似乎会导致应用程序停止执行

 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
是否需要另一列使其具有确定性?是的,我在连接后获得了更多的行,但是没有连接,正确的行数是正确的,但是当我添加连接时,它变为