2017-08-31 46 views
-1

我有两个表:DocumentsDocumentAttributes带两个不在的SQL语句

  • Document有关列DocIDDelFlag
  • DocumentAttributesDocIDaIDaValue

现在我希望所有DocIDs和A-值有以下限制:

SELECT 
    [o1].[docid] 
    , [o1].[aValue] 
FROM [DocumentAttributes] [o1] 
WHERE [o1].[aID] = 9 
     AND [o1].[DocID] >= 2356 
     AND [o1].[DocID] < 90000000 
     AND [o1].[DocID] NOT IN 
     (
      SELECT 
      [o].[DocID] 
      FROM [DocumentAttributes] [o] 
      WHERE [o].[aID] = 2 
     ) 
    AND [o1].[DocID] IN 
     (
      SELECT 
      [d].[DocID] 
      FROM [DOCUMENTS] [d] 
      WHERE [d].[DELFLAG] != 2 
     ); 

所以我想所有的文件h ave否AttributeID = 2且未标记为已删除的属性。

上面的SQL语句有效,但是由于我有大约1kk的文档,每个文档至少有10个属性,所以速度太慢。

3选择自己的成本不到1秒,所以“不在”是我猜的问题。

有没有人有一个想法如何使它更快?

预先感谢来自

+0

有几种技术,其中一些是RDBMS特有的,另一些则不是。有些想到的是“minus”或“except”关键字,“不存在”和“左连接”。 –

+0

标记您正在使用的dbms。 – jarlh

+0

它是一个oracle DB –

回答

0

子选择“不”语句的每一行,多数民众赞成你的事业中的一个执行,所以可能。

1

重新写入not in作为left join

select o1.docid, o1.aValue 
from DocumentAttributes o1 
left join DocumentAttributes o on o1.DocID = o.DocID and o.aID = 2 
where o1.aID = 9 and o1.DocID >= 2356 and o1.DocID < 90000000 
    and o.DocID is null 
and o1.DocID in (
    select d.DocID 
    from DOCUMENTS d 
    where d.DELFLAG != 2) 
0

Oracle支持的minus关键字。这意味着你可以取代这种东西

where myField not in (
select someField 
from etc 
) 

与这样的事情。

where myField in (
select someField 
from wherever 
where they are available 
minus 
select someField 
from the same tables 
where I want to exclude them 
) 

我建议试试这个和左连接方法,看看哪个更好。