此查询需要15秒

问题描述 投票:-3回答:2

我也添加了索引但仍然需要13秒

我为我在这里使用的所有列添加了复合索引

SELECT carrierbil2_.IDENTITY AS col_0_0_,
        carrier4_.CARRIER_NAME AS col_1_0_,
        carrier4_.IDENTITY AS col_2_0_,
        carrier4_.CARRIER_ID AS col_3_0_,
        shipmentor0_.EXTERNAL_REFERENCE_ID AS col_4_0_,
        invoicedet5_.INVOICE_NUMBER AS col_5_0_,`enter code here`
        shipmentca1_.CARRIER_REFERENCE_NUMBER AS col_6_0_,
        SUM(shipmentco9_.RATED_COST) AS col_7_0_,
        SUM(shipmentco9_.COST) AS col_8_0_,
        invoice6_.TOTAL_PAID_AMOUNT AS col_9_0_,
        invoice6_.INVOICE_GENERATED_DATE AS col_10_0_,
        shipmentor0_.ACTUAL_SHIP_DATE AS col_11_0_,
        bolstatus15_.BOL_STATUS_ID AS col_12_0_,
        shipmentlo10_.LOCATION_NAME AS col_13_0_,
        country11_.COUNTRY_NAME AS col_14_0_,
        postal14_.POSTAL_CODE AS col_15_0_,
        state12_.STATE_NAME AS col_16_0_,
        city13_.CITY_NAME AS col_17_0_,
        shipmentlo16_.LOCATION_NAME AS col_18_0_,
        country17_.COUNTRY_NAME AS col_19_0_,
        postal20_.POSTAL_CODE AS col_20_0_,
        state18_.STATE_NAME AS col_21_0_,
        city19_.CITY_NAME AS col_22_0_,
        shipmentor0_.IDENTITY AS col_23_0_,
        shipmentca1_.IDENTITY AS col_24_0_,
        shipmentno7_.NOTE AS col_25_0_
    FROM
        SHIPMENT_ORDER shipmentor0_
            INNER JOIN
        SHIPMENT_CARRIER shipmentca1_ ON shipmentor0_.SHIPMENT_ORDER_ID = shipmentca1_.SHIPMENT_ORDER_ID
            AND (shipmentca1_.IS_DELETED = 0)
            LEFT OUTER JOIN
        CARRIER_BILL_DETAILS carrierbil2_ ON shipmentca1_.SHIPMENT_CARRIER_ID = carrierbil2_.SHIPMENT_CARRIER_ID
            LEFT OUTER JOIN
        CARRIER_BILLS carrierbil3_ ON carrierbil2_.CARRIER_BILL_ID = carrierbil3_.CARRIER_BILL_ID
            INNER JOIN
        CARRIER carrier4_ ON shipmentca1_.CARRIER_ID = carrier4_.CARRIER_ID
            LEFT OUTER JOIN
        INVOICE_DETAILS invoicedet5_ ON shipmentor0_.SHIPMENT_ORDER_ID = invoicedet5_.SHIPMENT_ORDER_ID
            LEFT OUTER JOIN
        INVOICE invoice6_ ON invoicedet5_.INVOICE_ID = invoice6_.INVOICE_ID
            LEFT OUTER JOIN
        SHIPMENT_NOTES shipmentno7_ ON shipmentor0_.SHIPMENT_ORDER_ID = shipmentno7_.SHIPMENT_ORDER_ID
            AND (shipmentno7_.NOTE_TYPE = 4)
            LEFT OUTER JOIN
        SHIPMENT_COST shipmentco8_ ON shipmentor0_.SHIPMENT_ORDER_ID = shipmentco8_.SHIPMENT_ID
            LEFT OUTER JOIN
        SHIPMENT_COST_DETAILS shipmentco9_ ON shipmentco8_.SHIPMENT_COST_ID = shipmentco9_.SHIPMENT_COST_ID
            AND (shipmentco9_.IS_DELETED = 0)
            LEFT OUTER JOIN
        SHIPMENT_LOCATION shipmentlo10_ ON shipmentor0_.ORIGIN_ID = shipmentlo10_.SHIPMENT_LOCATION_ID
            AND (shipmentlo10_.LOCATION_TYPE_ID = 3)
            LEFT OUTER JOIN
        COUNTRY country11_ ON shipmentlo10_.COUNTRY_ID = country11_.COUNTRY_ID
            LEFT OUTER JOIN
        STATE state12_ ON shipmentlo10_.STATE_ID = state12_.STATE_ID
            LEFT OUTER JOIN
        CITY city13_ ON shipmentlo10_.CITY_ID = city13_.CITY_ID
            LEFT OUTER JOIN
        POSTAL postal14_ ON shipmentlo10_.POSTAL_ID = postal14_.POSTAL_ID
            LEFT OUTER JOIN
        BOL_STATUS bolstatus15_ ON shipmentor0_.ORDER_STATUS = bolstatus15_.BOL_STATUS_ID
            LEFT OUTER JOIN
        SHIPMENT_LOCATION shipmentlo16_ ON shipmentor0_.DESTINATION_LOCATION_ID = shipmentlo16_.SHIPMENT_LOCATION_ID
            AND (shipmentlo16_.LOCATION_TYPE_ID = 4)
            LEFT OUTER JOIN
        COUNTRY country17_ ON shipmentlo16_.COUNTRY_ID = country17_.COUNTRY_ID
            LEFT OUTER JOIN
        STATE state18_ ON shipmentlo16_.STATE_ID = state18_.STATE_ID
            LEFT OUTER JOIN
        CITY city19_ ON shipmentlo16_.CITY_ID = city19_.CITY_ID
            LEFT OUTER JOIN
        POSTAL postal20_ ON shipmentlo16_.POSTAL_ID = postal20_.POSTAL_ID
            CROSS JOIN
        CLIENT client21_
    WHERE
        shipmentor0_.CLIENT_ID = client21_.CLIENT_ID
            AND bolstatus15_.SEQUENCE_ID >= 700
            AND (carrierbil3_.IS_APPROVED = 0
            OR carrierbil3_.IS_APPROVED IS NULL)
            AND (carrierbil3_.IS_DELETED = 0
            OR carrierbil3_.IS_DELETED IS NULL)
            AND (carrierbil2_.IS_DELETED = 0
            OR carrierbil2_.IS_DELETED IS NULL)
            AND (shipmentor0_.IS_DELETED = 0
            OR shipmentor0_.IS_DELETED IS NULL)

    GROUP BY invoice6_.INVOICE_GENERATED_DATE , shipmentca1_.IDENTITY  , invoicedet5_.INVOICE_NUMBER , invoice6_.TOTAL_PAID_AMOUNT , shipmentca1_.CARRIER_REFERENCE_NUMBER , carrier4_.CARRIER_ID , CAST(carrier4_.IDENTITY AS SIGNED) , carrier4_.CARRIER_NAME , CAST(carrierbil2_.IDENTITY AS SIGNED) , shipmentor0_.SHIPMENT_ORDER_ID , shipmentno7_.NOTE , shipmentor0_.EXTERNAL_REFERENCE_ID , shipmentlo10_.LOCATION_NAME , country11_.COUNTRY_NAME , postal14_.POSTAL_CODE , state12_.STATE_NAME , city13_.CITY_NAME , shipmentlo16_.LOCATION_NAME , country17_.COUNTRY_NAME , postal20_.POSTAL_CODE , state18_.STATE_NAME , city19_.CITY_NAME , shipmentor0_.IDENTITY 
    ORDER BY shipmentor0_.SHIPMENT_ORDER_ID DESC;
mysql query-performance
2个回答
1
投票

由于OR,索引几乎没用,就像在

        AND (carrierbil3_.IS_APPROVED = 0
          OR carrierbil3_.IS_APPROVED IS NULL)

解决这个问题的简单方法是选择0或NULL来表示标志。然后确保所有数据都是一致的,并将WHERE更改为仅检查一个案例。

你真的是这个意思吗?

        CROSS JOIN
    CLIENT client21_

这可能是一个性能杀手并产生巨大的结果集。

没关系。你在ONWHERE。请使用ON进行关系,使用WHERE进行过滤。

  WHERE
    shipmentor0_.CLIENT_ID = client21_.CLIENT_ID

我看到LEFT JOINJOIN的混合物。检查LEFT JOINs真的需要LEFT;也就是说,'right'表可能缺少数据。

如需进一步讨论,请提供EXPLAIN SELECT ...

避免过度正常化:

您有5个表来描述位置(姓名,国家,邮政,州,城市)。相反,我建议使用包含这5列的单个表。仅此一项就可以摆脱8个JOINs

CAST(carrier4_.IDENTITY AS SIGNED) - 您不能将数据类型修复为SIGNED,或者允许该值为UNSIGNED吗?

但也许主要的表现杀手是“爆炸性内爆”综合症。首先,它做了很多JOINs,建立一个巨大的中间表,然后它通过做GROUP BY崩溃。补救措施是

SELECT ...
    FROM ( SELECT SUM(...), SUM(...) FROM ... GROUP BY ... ) AS a
    JOIN ((whatever else is needed));

也就是说,首先设计一个最小的“派生表”来执行GROUP BY(和/或ORDER BY和/或LIMIT)。然后看看完成查询还需要什么(即所有规范化查找)。

在您对我的大多数评论采取行动后,我们可以讨论您是否拥有最佳索引。 (现在这样做还为时过早。)如果是这样,请开始一个新的问题;添加到这个中会太杂乱。


-1
投票

首先,这是很多联接。但是,查询占用大量时间的主要原因是因为您要添加order by子句。你需要找到一种避免它的方法,或者可能想出一个不同的策略

© www.soinside.com 2019 - 2024. All rights reserved.