以前,在使用
WITH
子句和 IN
运算符时,我一直对 MySQL 和 SQLite 使用单独的代码。我在 MySQL 中使用 IN (TABLE cte)
,在 SQLite 中使用 IN cte
。
在看到像 this 和 this 这样的骗局之后,我对如何可移植地使用
WITH
子句和 IN
运算符有了一些了解 - 使用 SELECT
子句。这就是我现在所做的:
MySQL:
WITH cte AS (SELECT column1, column2 FROM Table1 WHERE ...)
SELECT * FROM Table2 WHERE ... AND ((column1, column2) IN (TABLE cte))
ORDER BY column3
SQLite:
WITH cte AS (SELECT column1, column2 FROM Table1 WHERE ...)
SELECT * FROM Table2 WHERE ... AND ((column1, column2) IN cte)
ORDER BY column3
但是,我有点担心性能。如果我执行以下操作:
便携式:
WITH cte AS (SELECT column1, column2 FROM Table1 WHERE ...)
SELECT * FROM Table2 WHERE ... AND ((column1, column2) IN (SELECT * FROM cte))
ORDER BY column3
Q1:如果
IN (SELECT * FROM cte)
是 cte
子句结果的一部分,那么第三个 select 子句(如 WITH
一样简单)执行起来会很麻烦吗?尤其是当Table2
很大的时候?
Q2:对于 MySQL 和 SQLite,他们是否对此应用了任何类型的优化?
如果您想要可移植性和性能,请不要使用 CTE 或
IN ( SELECT ... )
或“行构造函数”。这可能具有更好的便携性和性能:
SELECT table1.*
FROM Table2
JOIN table1 USING (column1, column2)
ORDER BY table1.column3
如果
USING
没有在任何地方处理,说
ON (table1.column1 = table2.column1
AND table1.column2 = table2.column2)