簡體   English   中英

MySQL 未在子查詢連接中使用索引

[英]MySQL is not using index in subquery join

我使用此查詢來總結倉位的元素及其子元素,以檢查價格是否正確。 當我運行這個查詢時,我得到了正確的結果,但是對於超過 200 萬行的元素表和超過 900 萬行的子元素,它工作了將近 2 分鍾。

我認為 MySQL 由於子查詢上的連接而沒有正確使用索引,但我不知道如何解決這個問題。

SELECT `pos`.`id`,
       `pos`.`Name`,
       `pos`.`Mark`,
       `pos`.`Number`,
       `elem`.`elemPrice`        as `elemPrice`,
       `elem`.`subelemPrice`     as `subelemPrice`,
       `pos`.`price`             as `price`,
       `elem`.`elemCalcPrice`    as `elemCalcPrice`,
       `elem`.`subelemCalcPrice` as `subelemCalcPrice`,
       `pos`.`supplier_webcalcprice`
FROM `proposal_draft_positions` `pos`
    LEFT JOIN (
        SELECT SUM(quantity * price)                    as elemPrice,
               SUM(quantity * supplier_webcalcprice)    as elemCalcPrice,
               SUM(quantity * subelem.subelemPrice)     as subelemPrice,
               SUM(quantity * subelem.subelemCalcPrice) as subelemCalcPrice,
               position,
               id,
               quantity
        FROM proposal_position_elements elm
        LEFT JOIN (
            SELECT SUM(price * quantity)                 as subelemPrice,
                   SUM(supplier_webcalcprice * quantity) as subelemCalcPrice,
                   element
            FROM proposal_position_subelements
            GROUP BY element) subelem ON subelem.element = elm.id
    GROUP BY position) elem ON `elem`.`position` = `pos`.`id`
WHERE `draft_id` = 29407

EXPLAIN 顯示 MySQL 沒有正確使用連接上的索引:

解釋結果

表 DDL:

create table proposal_draft_positions
(
    id                        int(10) auto_increment
        primary key,
    Number                    int(10)                               null,
    Mark                      varchar(200)                          null,
    Name                      json                                  null,
    price                     decimal(10, 2)           default 0.00 not null,
    supplier_webcalcprice     decimal(10, 2)           default 0.00 null,
)
    charset = utf8;


create table proposal_position_elements
(
    id                        int(30) auto_increment    primary key,
    position                  int(10)                   not null,
    quantity                  decimal(10, 2)            default 1.00 not null,
    price                     decimal(10, 2)            default 0.00 null,
    supplier_webcalcprice     decimal(10, 2)            default 0.00 null,
    constraint fk_proposal_position_elements
        foreign key (position) references proposal_draft_positions (id)
            on delete cascade
)
    charset = utf8;


create index `positions-elements-fk`
    on proposal_position_elements (position);




create table proposal_position_subelements
(
    id                        int(50) auto_increment
        primary key,
    element                   int(30)                                                                not null,
    quantity                  decimal(10, 2)                                          default 1.00   not null,
    price                     decimal(10, 2)                                          default 0.00   null,
    supplier_webcalcprice     decimal(10, 2)                                          default 0.00   null,
    constraint fk_proposal_position_subelements
        foreign key (element) references proposal_position_elements (id)
            on delete cascade
)
    charset = utf8;

create index `element-subelement-fk`
    on proposal_position_subelements (element);

由於 EXPLAIN 顯示 JOIN`ed 查詢是針對整個表運行的,我決定添加過濾並很少重寫查詢:

SELECT `pos`.`id`,
       `pos`.`Name`,
       `pos`.`Mark`,
       `pos`.`Number`,
       `pos`.`supplier_webcalcprice`,
       `pos`.`price`             as `price`,
       `elem`.`elemPrice`        as `elemPrice`,
       `elem`.`elemCalcPrice`    as `elemCalcPrice`,
       `elem`.`subelemPrice`     as `subelemPrice`,
       `elem`.`subelemCalcPrice` as `subelemCalcPrice`
FROM `proposal_draft_positions` `pos`
LEFT JOIN (
    SELECT SUM(elem.price * elem.quantity)                    as elemPrice,
           SUM(elem.supplier_webcalcprice * elem.quantity)    as elemCalcPrice,
           SUM(elem.quantity * subelem.subelemPrice)     as subelemPrice,
           SUM(elem.quantity * subelem.subelemCalcPrice) as subelemCalcPrice,
           elem.position,
           elem.id,
           elem.quantity
    FROM `proposal_draft_positions` pdp
    LEFT JOIN proposal_position_elements elem on pdp.id = elem.position
    LEFT JOIN (
        SELECT SUM(subelem.price * subelem.quantity)                 as subelemPrice,
               SUM(subelem.supplier_webcalcprice * subelem.quantity) as subelemCalcPrice,
               element
        FROM `proposal_draft_positions` pdp
        LEFT JOIN proposal_position_elements elem on pdp.id = elem.position
        LEFT JOIN proposal_position_subelements subelem on elem.id = subelem.element
        WHERE pdp.draft_id = 29407
        GROUP BY element) subelem ON subelem.element = elem.id
    WHERE pdp.draft_id = 29407
    GROUP BY position) elem ON `elem`.`position` = `pos`.`id`

WHERE `draft_id` = 29407;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM