SQL Db2 中的左连接而不是不存在

Posted

技术标签:

【中文标题】SQL Db2 中的左连接而不是不存在【英文标题】:Left Join instead of Not Exists in SQL Db2 【发布时间】:2021-06-03 08:24:54 【问题描述】:

由于性能不佳,我目前正在修改我的 SQL 查询。

因此查询检查表 A 和 B,并报告表 B 上是否缺少某些内容。 目前我正在使用“不存在”的解决方案,这导致必须完全选择两个表。这会导致性能不佳

SELECT A.DBNAME,                                     
       A.TSNAME,                                     
       VARCHAR(A.PARTITION)                          
FROM DUMMY.TABLEONE A WHERE NOT EXISTS          
   (SELECT B.DBNAME                                  
          ,B.TSNAME                                  
          ,B.LOGICAL_PART                            
          ,B.ICDATE                                  
          ,B.ICTYPE                                  
           FROM DUMMY.TABLETWO B                     
   WHERE B.DBNAME = A.DBNAME AND B.TSNAME = A.TSNAME 
   AND   A.PARTITION = B.LOGICAL_PART                
   AND   B.ICTYPE = 'F'                              
   AND   B.ICDATE > CURRENT DATE - 7 DAYS);      

这个查询给了我正确的结果集,但是性能很差。

我尝试重写为left Join:

SELECT A.DBNAME,                                       
       A.TSNAME,                                       
       VARCHAR(A.PARTITION)                            
FROM DUMMY.TABLEONE A                             
LEFT JOIN                                              
DUMMY.TABLETWO B                                       
ON A.DBNAME = B.DBNAME AND                             
   A.TSNAME = B.TSNAME AND                             
   A.PARTITION = B.LOGICAL_PART                        
   WHERE B.DBNAME IS NULL                              
   OR  (A.DBNAME = B.DBNAME AND                        
        A.TSNAME = B.TSNAME AND                        
        A.PARTITION = B.LOGICAL_PART AND               
        B.ICDATE > CURRENT DATE - 7 DAYS);                 

但是由于表 B 上的条目没有被删除,我得到的结果太多了。 我只想检索表 A 上的条目,其中表 B 上过去 7 天内没有相应的条目。 旧条目必须保留,否则我会实施管家解决方案。

提前感谢您的帮助

【问题讨论】:

【参考方案1】:

您可以考虑如下索引TABLETWO 表:

CREATE INDEX tt_idx ON DUMMY.TABLETWO (DBNAME, TSNAME, LOGICAL_PART, ICTYPE, ICDATE);

对于TABLEONE 表中的每条记录,这应该允许exists 逻辑更快地执行。此外,您可以将存在的语法简化如下:

SELECT A.DBNAME, A.TSNAME, VARCHAR(A.PARTITION)
FROM DUMMY.TABLEONE A
WHERE NOT EXISTS (
    SELECT 1
    FROM DUMMY.TABLETWO B
    WHERE B.DBNAME = A.DBNAME AND
          B.TSNAME = A.TSNAME AND
          A.PARTITION = B.LOGICAL_PART AND
          B.ICTYPE = 'F' AND
          B.ICDATE > CURRENT DATE - 7 DAYS
);

【讨论】:

嗨蒂姆感谢您的快速回复。当然,索引会极大地提高性能。我不知道为什么我没有想到这一点。

以上是关于SQL Db2 中的左连接而不是不存在的主要内容,如果未能解决你的问题,请参考以下文章

选择中的左连接与子查询的奇怪问题

sql中的左连接和右连接

删除...在sqlite中的左连接查询[重复]

Laravel Lumen 雄辩的左连接返回连接表数据而不是主数据

Linq 和 SQL的左连接右连接内链接

SQL中的左连接与右连接,内连接有啥区别