作者:BB_KYLE | 来源:互联网 | 2023-10-11 06:57
第一种语法通常更有效。
MySQL
缓冲派生查询,因此使用派生查询user_profile
消除了成为联接中驱动表的可能性。
即使user_profile
领先,子查询结果也应首先进行缓冲,这将对内存和性能产生影响。
将ALIMIT
应用于查询会使第一个查询快得多,而第二个查询则不然。
这是示例计划。(val, nid)
表格中有一个索引t_source
:
第一个查询:
EXPLAIN
SELECT *
FROM t_source s1
JOIN t_source s2
ON s2.nid = s1.id
WHERE s2.val = 1
1, 'SIMPLE', 's1', 'ALL', 'PRIMARY', '', '', '', 1000000, ''
1, 'SIMPLE', 's2', 'ref', 'ix_source_val,ix_source_val_nid,ix_source_vald_nid', 'ix_source_val_nid', '8', 'const,test.s1.id', 1, 'Using where'
第二个查询:
EXPLAIN
SELECT *
FROM t_source s1
JOIN (
SELECT nid
FROM t_source s2
WHERE val = 1
) q
ON q.nid = s1.id
1, 'PRIMARY', '', 'ALL', '', '', '', '', 100000, ''
1, 'PRIMARY', 's1', 'ref', 'PRIMARY', 'PRIMARY', '4', 'q.nid', 10000, 'Using where'
2, 'DERIVED', 's2', 'ref', 'ix_source_val,ix_source_val_nid,ix_source_vald_nid', 'ix_source_vald_nid', '4', '', 91324, 'Using index'
如您所见,在第二种情况下,仅使用索引的一部分,并且q
被强制为前导。
派生查询 (此问题所关注的)不要与 子查询 相混淆。
虽然MySQL
无法优化 (在FROM
子句中使用的 ),但 (与IN
或一起使用的EXISTS
)的处理要好得多。