0

JOIN注文に基づいて、MySQL データベースから特定の情報を取得するための半複雑な構造があります。まず、SQL クエリを示します。

SELECT
    #orders.*,
    orders.id,
    customers.lastname,
    customers.priority,
    shipments.status,
    pmv_sl.productmodelvariant_id,
    pmv_sl.nr AS pmv_nr,
    COALESCE(SUM(orderlines.nr), 0) AS orderlines_nr_count,
    COALESCE(SUM(shipment_lines.nr), 0) AS shipment_lines_nr_count
FROM orders
    INNER JOIN  customers       ON customers.id = orders.customer_id
    INNER JOIN  platforms       ON platforms.id = orders.platform_id
    INNER JOIN  stocklocations  ON stocklocations.id = platforms.stocklocation_id
    LEFT JOIN   orderlines      ON orderlines.order_id = orders.id
    LEFT JOIN   shipments       ON shipments.order_id = orders.id
    LEFT JOIN   shipment_lines  ON shipment_lines.shipment_id = shipments.id

    # This JOIN, together with shipment_lines, makes the query suddenly very slow (probably because of all the SUM()'s)
    LEFT JOIN   productmodelvariants_stocklocations pmv_sl ON
        pmv_sl.productmodelvariant_id = orderlines.productmodelvariant_id
        AND pmv_sl.stocklocation_id = stocklocations.id
WHERE
    orders.orderstatus_id = 2
    AND orders.order_all_to_shipment = 0
GROUP BY
    orders.id

問題

したがって、このクエリの 4 つの速度を計算しました (すべてのケースで 450 の結果)。

  1. なしLEFT JOIN shipment_linesとなしLEFT JOIN productmodelvariants_stocklocations
  2. LEFT JOIN shipment_linesだけで
  3. LEFT JOIN productmodelvariants_stocklocationsだけで
  4. 2.と_3.

結果の速度は次のとおりです。

  1. 0.146秒
  2. 1.975秒
  3. 0.234秒
  4. 4.619秒

表の行

  • orderlines数: 24528
  • shipment_lines数: 6345
  • productmodelvariants_stocklocations: 1819

結論

ご覧のとおり、1 回2.3.( で4.) 両方がレースに参加します。SQL は汗をかき始めます。

私よりも (My)SQL の知識が豊富な人は、クエリのコンテキストを変更して少し向上させる方法を知っているのではないかと思います。

4.また、 を実行して引用すると、COALESCE(SUM()簡単0.8に数秒になることにも気付きました1.0

アップデート

拡張された説明

拡張された説明

4

2 に答える 2

2

shippings.status での結合句の指定に失敗してクロス結合を作成しています

次のようにクエリを再編成してみてください。

SELECT A.*, 
    orders_id,
    customers.lastname,
    customers.priority,
#    shipments.status,
    pmv_sl.productmodelvariant_id,
    pmv_sl.nr AS pmv_nr,
    orderlines_nr_count,
    shipment_lines_nr_count
FROM (
  SELECT
      #orders.*,
      orders.id AS orders_id,
#      shipments.status,
      COALESCE(SUM(orderlines.nr), 0) AS orderlines_nr_count,
      COALESCE(SUM(shipment_lines.nr), 0) AS shipment_lines_nr_count
  FROM orders
      LEFT JOIN   orderlines      ON orderlines.order_id = orders.id
      LEFT JOIN   shipments       ON shipments.order_id = orders.id
      LEFT JOIN   shipment_lines  ON shipment_lines.shipment_id = shipments.id

  WHERE orders.orderstatus_id = 2
   AND orders.order_all_to_shipment = 0
  GROUP BY 
      orders.id,
      orderlines.productmodelvariant_id,
      stocklocations.id
) orders
    INNER JOIN  customers       ON customers.id = orders.customer_id
    INNER JOIN  platforms       ON platforms.id = orders.platform_id
    INNER JOIN  stocklocations  ON stocklocations.id = platforms.stocklocation_id
    LEFT JOIN   productmodelvariants_stocklocations pmv_sl ON
      pmv_sl.productmodelvariant_id = orderlines.productmodelvariant_id
      AND pmv_sl.stocklocation_id = stocklocations.id
GROUP BY
    orders.id

次に、出荷ステータスがどこに行くかを把握します。

于 2013-04-28T18:31:09.103 に答える