этот запрос занимает 15 секунд - PullRequest
0 голосов
/ 11 марта 2019

я также добавил индексы, но все же это занимает 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;

Ответы [ 2 ]

1 голос
/ 13 марта 2019

Индексы в основном бесполезны из-за OR, как в

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

Простой способ исправить это выбрать либо 0 или NULL для представления флага.Затем убедитесь, что все данные согласованы, и измените WHERE, чтобы просто проверить один случай.

Вы действительно означает

        CROSS JOIN
    CLIENT client21_

То естьскорее всего, это повлияет на производительность и создаст огромный набор результатов.

Не берите в голову.У вас есть ON в WHERE.Пожалуйста, используйте ON для отношений и WHERE для фильтрации.

  WHERE
    shipmentor0_.CLIENT_ID = client21_.CLIENT_ID

Я вижу смесь LEFT JOIN и JOIN.Убедитесь, что LEFT JOINs действительно должно быть LEFT;то есть в «правильной» таблице могут отсутствовать данные.

Для дальнейшего обсуждения предоставьте EXPLAIN SELECT ....

Отказ от нормализации:

У вас есть 5 таблицописать местоположение (название, страна, почтовый индекс, штат, город).Вместо этого я рекомендую таблицу single с этими 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).Затем посмотрите, что еще нужно для выполнения запроса (а именно все поиски нормализации).

После того, как вы ответили на большинство моих комментариев, мы можем обсудить, есть ли у вас оптимальные индексы.(Сейчас делать это преждевременно.) Если это так, пожалуйста, начните новый Вопрос;было бы слишком много беспорядка, чтобы добавить к этому.

0 голосов
/ 11 марта 2019

Прежде всего, это много объединений.Однако основная причина, по которой ваш запрос занимает значительное время, заключается в том, что вы добавляете заказ по предложению.Вам нужно найти способ избежать этого, или, может быть, придумаете другую стратегию

...