优化选择查询。使用了join,Not in和sub查询

时间:2018-04-23 11:41:18

标签: mysql query-performance

我正在尝试优化以下查询:

Select distinct cadData.id FROM CAD_Data cadData 
INNER JOIN Sales_Data SD 
ON cadData.CAD_Acct=SD.CAD_Acct 
and SD.List_Date = (
                    select max(List_Date) 
                    from Sales_Data 
                    where Sales_Data.CAD_Acct=cadData.CAD_Acct 
                   )  
where cadData.GMA_Tag = 101 
AND SD.List_Status NOT IN('ACT','OP','PEND','PSHO','pnd')  
ORDER BY cadData.id asc limit 10

这两个表都有超过1000万行。 CAD_Data表由CAD_Acct和GMA_Tag列索引。除了Sales_data之外,还有CAD_Acct,GMA_Tag,List_Date,List_Status列索引。解释显示enter image description here

我需要一些优化此查询的建议。提前谢谢。

3 个答案:

答案 0 :(得分:0)

Select distinct cadData.id 
FROM CAD_Data cadData 
INNER JOIN Sales_Data SD 
ON cadData.CAD_Acct=SD.CAD_Acct 
INNER JOIN
(
select CAD_Acct,max(List_Date) AS List_Date 
from Sales_Data
GROUP BY CAD_Acct 
) T
ON SD.List_Date=T.List_Date
AND T.CAD_Acct=cadData.CAD_Acct
where cadData.GMA_Tag = 101 
AND SD.List_Status NOT IN('ACT','OP','PEND','PSHO','pnd')  
ORDER BY cadData.id asc limit 10

答案 1 :(得分:0)

做杰伊建议,但也提供这些索引:

SD:  INDEX(List_Date)
cadData:  INDEX(GMA_Tag, CAD_Acct, id)  -- in this order
杰伊的重新制定要求从子查询开始。这意味着需要存在索引以便以不同的顺序处理表。

请提供SHOW CREATE TABLE和新的EXPLAIN

答案 2 :(得分:0)

确保您已准备好这些索引:

ALTER TABLE `CAD_Data` ADD INDEX `cad_data_idx_tag_id` (`GMA_Tag`,`id`);
ALTER TABLE `CAD_Data` ADD INDEX `cad_data_idx_id` (`id`);
ALTER TABLE `CAD_Data` ADD INDEX `cad_data_idx_acct` (`CAD_Acct`);
ALTER TABLE `Sales_Data` ADD INDEX `sales_data_idx_status_acct` (`List_Status`,`CAD_Acct`);

创建它们后,尝试运行此查询转换:

SELECT 
    cadData.id
FROM
    CAD_Data cadData
WHERE
    cadData.GMA_Tag = 101 
        AND EXISTS( SELECT 
            *
        FROM
            Sales_Data SD
                LEFT JOIN
            Sales_Data AS Sales_Data1 ON Sales_Data1.CAD_Acct = cadData.CAD_Acct
                AND Sales_Data1.List_Date < cadData.CAD_Acct
        WHERE
            cadData.CAD_Acct = SD.CAD_Acct
                AND SD.List_Status NOT IN ('ACT' , 'OP', 'PEND', 'PSHO', 'pnd')
                AND cadData.CAD_Acct IS NULL)
ORDER BY cadData.id ASC
LIMIT 10