加速mysql查询

huwehgph  于 2021-06-19  发布在  Mysql
关注(0)|答案(4)|浏览(384)

我有一个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


我的问题真的是需要很多时间才能完成的查询。有没有一种方法可以加速这个查询或更改这个查询以更快地检索数据?
这是评论中要求的解释。

提前谢谢,我真的希望这是我问的正确渠道。如果没有请告诉我。

1cosmwyk

1cosmwyk1#

首先,我清理了一点可读性。你不需要 tick 在每个表的周围做标记。列引用。另外,简而言之,使用别名也很有效。例如:“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
hrysbysz

hrysbysz2#

你要确定 purchase_order.po_date 所有id列都被索引。您可以通过下面的查询进行检查。

SHOW INDEX FROM yourtable;
jgzswidk

jgzswidk3#

自从你提到数据越来越大。我建议做切分,然后你可以并行多个查询。请参考以下文章
基于shard查询的mysql并行查询

w51jfk4q

w51jfk4q4#

这会给你正确的ID列表吗?

SELECT id
    FROM purchase_order
    ORDER BY`po_date` DESC
    LIMIT 0, 20

如果是这样的话,那么在发射到 JOIN . 你也可以(我认为)摆脱 GROUP BY 这导致了行的“爆炸-内爆”。

SELECT ...
    FROM ( SELECT id ... (as above) ...) AS ids
    JOIN purchase_order po  ON po.id = ids.id
    JOIN ... (the other tables)
    GROUP BY ...   -- (this may be problematic, especially with the LIMIT)
    ORDER BY po.po_date DESC   -- yes, this needs repeating
    -- no LIMIT

像这样的

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

相关问题