Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
压缩速度更快的MySQL总和+;加入_Mysql_Sql - Fatal编程技术网

压缩速度更快的MySQL总和+;加入

压缩速度更快的MySQL总和+;加入,mysql,sql,Mysql,Sql,我有一个半复杂的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)

我有一个半复杂的
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个结果)

  • LEFT-JOIN发货行
    和无
    LEFT-JOIN-productmodelvariants\u库存位置
  • 仅使用
    左连接装运线
  • 仅使用
    左键连接productmodelvariants\u stocklocations
  • 同时使用
    2.
    3.
  • 这里是结果速度

  • 0.146秒
  • 1.975秒
  • 0.234秒
  • 4.619秒
  • 表格中的行

    • 订单行中的行
      :24528
    • 装运行中的行:6345
    • productmodelvariants\u stocklocations
      中的行:1819
    结论

    正如你曾经看到的那样,
    2.
    3.
    (在
    4.
    )都加入了比赛;SQL开始出汗了

    我想知道是否有比我更了解(我的)SQL的人知道一种方法来改变查询的上下文以提高它的性能

    我还注意到,当执行
    4.
    并引用
    合并(SUM()
    )时,我很容易获得
    0.8到
    1.0

    更新

    解释扩展


    由于未能在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
    

    然后找出装运状态的位置。

    您没有在shippings.status上指定join子句,这是在创建交叉联接

    尝试按如下方式重新组织查询:

    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
    

    然后找出发货状态的位置。

    您的查询是对任何给定的订单在订单和发货之间进行笛卡尔联接。更好的方法是在进行联接之前,将所有内容汇总到
    订单id
    级别:

    SELECT
        #orders.*,
        orders.id,
        customers.lastname,
        customers.priority,
        shipments.status,
        pmv_sl.productmodelvariant_id,
        pmv_sl.nr AS pmv_nr,
        COALESCE(ol.orderlines_nr_count, 0) AS orderlines_nr_count,
        COALESCE(sl.shipment_lines_nr_count, 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  
        (select order_id, SUM(orderlines.nr) as orderline_nr_count
         from orderlines
         group by order_id
        ) ol ON ol.order_id = orders.id
        LEFT JOIN   shipments       ON shipments.order_id = orders.id
        LEFT JOIN
        (select order_id, SUM(shipment_lines.nr) shipment_lines_nr_count
         from shipment_lines 
         group by order_id
        ) sl ON sl.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
    
    这是一个近似值,因为我看到的唯一聚合函数是针对订单行和发货行的。例如,如果每个订单有多个发货,则必须找出如何将其压缩到一个状态(原始查询将任意选择一个,此查询也是如此)


    如果您仅在
    订单id
    级别将表/子查询联接在一起,则最终的
    分组依据将是不必要的。

    对于任何给定的订单,您的查询在订单和装运之间进行笛卡尔联接。更好的方法是在联接之前将所有内容汇总到
    订单id
    级别:

    SELECT
        #orders.*,
        orders.id,
        customers.lastname,
        customers.priority,
        shipments.status,
        pmv_sl.productmodelvariant_id,
        pmv_sl.nr AS pmv_nr,
        COALESCE(ol.orderlines_nr_count, 0) AS orderlines_nr_count,
        COALESCE(sl.shipment_lines_nr_count, 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  
        (select order_id, SUM(orderlines.nr) as orderline_nr_count
         from orderlines
         group by order_id
        ) ol ON ol.order_id = orders.id
        LEFT JOIN   shipments       ON shipments.order_id = orders.id
        LEFT JOIN
        (select order_id, SUM(shipment_lines.nr) shipment_lines_nr_count
         from shipment_lines 
         group by order_id
        ) sl ON sl.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
    
    这是一个近似值,因为我看到的唯一聚合函数是针对订单行和发货行的。例如,如果每个订单有多个发货,则必须找出如何将其压缩到一个状态(原始查询将任意选择一个,此查询也是如此)


    如果您仅在
    订单id
    级别将表/子查询连接在一起,那么最终的
    分组依据将是不必要的。

    您是否在
    发货行上有索引。nr
    订单行。nr
    ?如果有,是什么类型的索引?只是一个问题。很好的一点;我的主要和相对id上只有
    索引。你认为它会有多大的影响?我不希望它会对这些表的总体性能产生太大的影响,因为这主要是添加太多
    索引的问题:PI已经将索引添加到两个表的
    nr
    字段中。遗憾的是,速度没有提高。甚至完全一样。编辑:添加到nr
    ode>productmodelvariants\u stocklocations
    也一样。也没有改进。您确定在这种情况下需要使用左连接吗?是的,否则一些想要的结果将被排除。此外,即使我将它们全部设置为
    内部
    进行测试。我返回了
    219
    行,遗憾的是,它们仍然运行
    3.825秒
    。因此相对而言,它是n甚至是一个很大的收获。你在
    发货行.nr
    订单行.nr
    上有索引吗?如果有,是什么类型的索引?只是一个问题。很好的观点;我只在我的主ID和相对ID上有
    索引。你认为它会有多大的影响?我不希望它会对这些表的总体性能产生太大的影响,a这主要是添加太多
    索引的问题:PI已经将索引添加到两个表的
    nr
    字段中。遗憾的是,速度没有提高。甚至完全相同。编辑:也添加到
    productmodelvariants\u stocklocations
    nr
    。也没有改进。您确定需要使用左连接i吗在这种情况下?是的,否则一些想要的结果将被排除在外。而且,即使我将它们全部设置为
    内部
    进行测试。我返回了
    219行
    行,它们仍然运行
    3.825秒
    。很遗憾,相对而言,这算不上什么大的收益。感谢您的回答!出于某种奇怪的原因,
    之后的第一个
    内部联接
    (…)订单
    失败(
    customers.id=orders.customer\u id
    )(错误代码1054)。它们无法连接?子选择必须在所选字段中的SELECT子句中包含客户id。
    (选择orders.customer\u id作为客户id,…)订单内部连接…
    对平台id执行与我建议的客户id相同的操作
    错误代码:1054。“on子句”中的未知列“orderlines.productmodelvariant\u id”
    。我在SELECT子句中执行了此操作
    orderlines.productmodelvariant\u id作为productmodelvariant\u id,
    ,但它没有抓住它。感谢您的回答!由于某种奇怪的原因,
    (…)订单之后的第一个
    内部联接
    失败(
    customers.id=orders.customer\u id
    )(错误代码1054)。它们无法连接?子选择必须在