对于大型结果集,Mysql NOT IN运算符性能问题?

时间:2009-11-09 17:02:55

标签: sql mysql performance

我有以下两个问题:

select   count(*) 
from     segmentation_cycle_recipients scr
         , segmentation_instance si 
where    si.access_code=scr.access_code 
         and si.segment_id is NOT NULL; 

在0.2秒内返回13429行

2)

select   count(*) 
from     segmentation_cycle_recipients scr
        , segmentation_instance si, web_pat_info wpi 
where    si.access_code=scr.access_code and scr.siebel_row_id=wpi.siebel_id 
         and si.segment_id is NOT NULL; 

在0.48秒内返回4003行

现在,我想1)-2)所以我写了以下查询:

select   count(*) 
from     segmentation_cycle_recipients scr
         , segmentation_instance si 
where    si.access_code=scr.access_code 
         and si.segment_id is NOT NULL 
         and scr.siebel_row_id NOT IN (select scr.siebel_row_id 
from     segmentation_cycle_recipients scr
         , segmentation_instance si
         , web_pat_info wpi where si.access_code=scr.access_code 
        and scr.siebel_row_id=wpi.siebel_id and si.segment_id is NOT NULL); 

我期待13429-4003 = 9426行,但查询需要永远(必须终止查询命令)才能执行。它甚至在mysql> status;)的“慢查询”列表中添加了一个计数器;)

它返回<在开发环境中100ms,结果集要小得多。所以我相信查询本身是正确的。

我相信,使用NOT IN是Mysql中已知的性能问题(Oracle有MINUS运算符)。有关如何提高此查询性能的任何建议吗?

2 个答案:

答案 0 :(得分:2)

SELECT  COUNT(*)
FROM    segmentation_cycle_recipients scr
JOIN    segmentation_instancs si
ON      si.access_code = scr.access_code
LEFT JOIN
        web_pat_info wpi 
ON      wpi.siebel_id = scr.siebel_row_id
WHERE   wpi.siebel_id IS NULL
        AND si.segment_id is NOT NULL

确保将si.access_codewpi.siebel_id编入索引,并将wpi.siebel_id定义为NOT NULL

如果后一个条件不成立,请将wpi.siebel_id IS NULL子句中的WHERE替换为定义为NOT NULL的任何其他列。

答案 1 :(得分:1)

使用NOT EXISTS子句可能会更好。

select   count(*) 
from     segmentation_cycle_recipients scr
         , segmentation_instance si 
where    si.access_code=scr.access_code 
         and si.segment_id is NOT NULL 
         and NOT EXISTS (select scr2.siebel_row_id 
from     segmentation_cycle_recipients scr2
         , segmentation_instance si2
         , web_pat_info wpi2 where si2.access_code=scr2.access_code 
        and scr2.siebel_row_id=wpi2.siebel_id and si2.segment_id is NOT NULL
        and scr.siebel_row_id=scr2.siebel_row_id);