以下查询:
SELECT
`so`.*,
IF(
ISNULL(`ips`.`border`),
`io`.`cdborder`,
`ips`.`border`
) AS order_status,
IF(
ISNULL(`ips`.`status`),
`io`.`cdstatus`,
`ips`.`status`
) AS order_state,
`io`.*,
IF(
ISNULL(`ips`.`sale`),
`iol`.`regelstatus`,
`ips`.`sale`
) AS order_line_status
FROM
`sales_order` AS `so`
INNER JOIN `sales_flat_order_item` AS `soi`
ON soi.order_id = so.entity_id
LEFT JOIN `import`.`import_orders` AS `io`
ON so.atorder_id = io.cdorder
AND so.cdadmin = io.cdadmin
AND (error_msg IS NULL
OR error_msg = "")
LEFT JOIN `import`.`import_orderlines` AS `iol`
ON iol.cdorder = so.atorder_id
AND iol.cdadmin = so.cdadmin
LEFT JOIN `import`.`import_purchase_sales` AS `ips`
ON so.atorder_id = ips.order
WHERE (soi.sku IS NULL)
OR (
soi.sku = iol.cdproduct
AND (
soi.atorder_line = iol.nrordrgl
)
AND (
iol.atg != soi.qty_shipped
OR iol.at != soi.qty_invoiced
OR iol.atb != soi.qty_ordered
)
)
GROUP BY `so`.`atorder_id`,
`so`.`cdadmin`
ORDER BY `io`.`modification_date_order` ASC
LIMIT 200
需要4分钟才能执行!怎么会这样?说明如下:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE so index PRIMARY order_id 32 NULL 127828 Using temporary; Using filesort
1 SIMPLE io eq_ref PRIMARY,error_msg PRIMARY 261 livetest3.so.order_id,livetest3.so.cdadmin 1
1 SIMPLE soi ref IDX_ORDER IDX_ORDER 4 livetest3.so.entity_id 2
1 SIMPLE iol ref cdorder cdorder 258 livetest3.so.order_id 6 Using where
1 SIMPLE ips ref sale_order sale_order 32 livetest3.so.order_id 3
我尝试了多个查询分析器工具,但没有向我显示有关查询哪个部分太慢的详细信息......
'so'表只包含130k行......即使有一堆左连接也不应该这么慢......有什么想法吗?
答案 0 :(得分:1)
EXPLAIN为您提供了所有必需的信息。 Using temporary; Using filesort
部分是缓慢的部分。
答案 1 :(得分:1)
主键似乎是order_id
,但您的查询根本无法使用它。如果您在sku
上创建索引,则查询应该运行得更快。
请注意,还有进一步改进的余地,但我首先要在sku
上创建一个索引,然后重新运行查询以查看它现在的执行情况。
答案 2 :(得分:1)
如果不确切知道您想要从数据中得到什么,您的查询就会有一个“soi.sku IS NULL”的实例,这意味着对该别名的LEFT JOIN。你有一个正常的连接表明你总是想要一个记录匹配“soi”你的意思是把它带到LEFT JOIN吗?如果你总是想要“soi”,那么我会删除查询中“soi.sku IS NULL OR”的部分。
除此之外,查询本身看起来还不错,但是,我会确保你明确地拥有以下索引。
Table Index
Sales_Order (atorder_id, ccadmin)
import.import_orderlines (cdorder, cdadmin)
import.import_orders (cdorder, cdadmin)
import.import_purchase_sales (order)
然后,改变
SELECT ...
到
SELECT STRAIGHT_JOIN ...