![](/img/trans.png)
[英]Subquery (and query with join) not using index with MySQL (MyISAM)
[英]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.