我正在编写一个查询,根据其他表中满足的某些条件来确定数据库中是否存在记录。
现在我想出了一种情况,我需要知道什么是最好的方法:
或者子查询:
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
最佳答案
通过使用左连接,它仅使用索引(前提是您的表在每个相应的“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
关于mysql - 使用 Exists 时,我应该对多个子查询使用 OR 还是对所有子查询使用 UNION?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23369243/