您最简单的方法(不太可能导致性能问题)将遍历元组并为每个元组生成一个 AND 条件,用括号括起来并由 OR 条件连接,从而生成查询:
SELECT *
FROM table
WHERE (col1 = 1 AND col3 = 1)
OR (col1 = 2 AND col3 = 1)
OR (...)
不过,您是对的,因为这可能不会很好地扩展。您可以改为首先分析您在 WHERE 子句中使用其值的元组,以便生成一个更紧凑的条件,对于每个唯一的可接受 col1 值,OR 将所有可接受的 col3 值组合在一起,然后将它们与 col1价值。例如,考虑元组(1, 1)
、(1, 2)
、(2, 1)
、(2, 3)
以及从它们生成的以下查询:
SELECT *
FROM table
WHERE (col1 = 1 AND (col3 = 1 OR col3 = 2))
OR (col1 = 2 AND (col3 = 1 OR col3 = 3))
这比第一种方法的结果要简单一些,并且需要提前付出更多的努力,但它可能会执行得更快,因为 AND 短路意味着数据库引擎可以更快地确定给定行是否将满足 WHERE 子句;它不需要为每一行单独检查每个(col1 = @m AND col2 = @n)
条件,它可以简单地检查该行的 col1 值是否匹配,如果不匹配则忽略其余条件。
(当然,MySQL 的查询优化器应该已经为你做这件事了,虽然它需要彻底的基准测试才能确定,但鉴于优化的明显性,我非常怀疑你是免费获得的。第二种形式的但是,查询仍然更易于阅读,这对您来说可能很重要,也可能无关紧要。)
无论如何,如果您需要在许多可接受值的元组中执行此操作,您将生成一个相对复杂的查询或一堆头脑简单的查询;每种方法都有优点和缺点,但考虑到您的要求和输入,我倾向于怀疑您是否会找到一种算法,该算法会生成一个更紧凑的查询,并且在它行为不端时仍然具有足够的可读性以进行调试。
如果您担心性能,我建议您等到证明存在性能问题后再担心。如果您已经这样做了,请检查您正在查询的表上的索引;如果您还没有在 WHERE 条件下使用的列中创建索引,那么现在是这样做的好时机。