当使用Exists时,我应该使用OR与多个子查询或UNION所有子查询吗?

时间:2014-04-29 15:40:50

标签: mysql performance optimization

我正在编写一个查询,以根据其他表中遇到的某些条件确定数据库中是否存在记录。

现在我想出了一种情况,我需要知道什么是最好的方法:

OR子查询:

SELECT * from table as tbl WHERE
Exists
(SELECT 1 FROM t1 WHERE t1.id = tbl.id)
OR Exists
(SELECT 1 FROM t2 WHERE t2.col2 = tbl.col2)
OR Exists
(SELECT 1 FROM t3 WHERE t3.othercol = tbl.somecol)

或使用没有OR的UNION:

SELECT * from tbl WHERE
Exists
(SELECT 1 FROM t1 WHERE t1.id = tbl.id
 UNION
 SELECT 1 FROM t2 WHERE t2.col2 = tbl.col2)
 UNION
 SELECT 1 FROM t3 WHERE t3.othercol = tbl.somecol)

我需要这是性能最好的,因此问题。 某些字段/列可能未被编入索引,这可能发生在一组不同的列中,而不仅仅是每个子查询/表的3个,甚至可能超过1个。

为了获得最佳解决方案,我将在此处发布一些复杂的示例: 如何加入连接?

SELECT * from table as cli WHERE
Exists 
        (

        SELECT 
            1
        from 
            tbl_import_line_reference as l,
            tbl_import_doc as d
        WHERE
            d.import_key = l.import_key AND
            CAST(Left(d.doc_date,8) as  DATE) BETWEEN  LAST_DAY(NOW() - INTERVAL 6 MONTH) + INTERVAL 1 day AND  NOW()
        AND
            l.prod_ref like '---fmidref%'
        AND
            d.doc_type ='F'
        AND 
            d.car_miposreg_ext_id = cli.car_miposreg_ext_id
        )

    OR
    Exists
        (

        select 
            1
        from 
            tbl_import_line_reference as l,
            tbl_import_doc as d
        WHERE
            d.import_key = l.import_key AND
            CAST(Left(d.doc_date,8) as  DATE) BETWEEN  @data_final + INTERVAL 1 day AND  NOW()
        AND
            l.prod_ref not RLIKE '---fmidneo|---fmidevo'
        AND
            l.act_code = 5
        AND
            l.act_subcode = "7"
        AND
            d.doc_type ='F'
        AND 
            d.car_miposreg_ext_id = cli.car_miposreg_ext_id
        )

之后:http://pastebin.com/gTFBFurV变为:http://pastebin.com/y13xKcMg

1 个答案:

答案 0 :(得分:2)

通过使用左连接,它仅使用索引(假设您的表在每个相应的" ID"," col2"和" othercol"基础。索引非常快,不需要去原始页面来确认它是否存在"或者不存在.where子句只关心任何元素NOT NULL(表明它存在于底层表)

SELECT 
      tbl.* 
   from 
      table as tbl
         LEFT JOIN t1
            ON tbl.id = t1.id
         LEFT JOIN t2
            ON tbl.col2 = t2.col2
         LEFT JOIN t3
            ON tbl.somecol = t3.othercol
   WHERE
         t1.ID is not null
      OR t2.col2 is not null
      OR t3.othercol is not null