感谢答复,leading属于半自动挡,straight_join属于完全手动挡。在较为复杂的查询场景下,只是局部顺序存在问题,那么通过leading可以让局部手动调整,在整体上还是优化器自动调整,因此会减少复杂度。straight_join对于复杂情况尤其较多张表关联,那么全部指定join顺序对DBA来说也是较为困难的。而且对于(a,b),(c,d) 这种连表顺序不修改SQL很难达到想要的结果,即使用了straight_join(很多复杂SQL可能是拼装生成的,不允许修改SQL顺序,这就导致straight_join受限)。
另外,关于这块表达能力最好的我认为当属DB2的hint,采用了xml的表达方式,可以表达出来几乎所有的优化器能表达的场景,针对我们这里简单的(a,b),(c,d)关联方式可以对标如下:
<HSJOIN>
<JOIN>
<ACCESS TABLE='a'/>
<LPREFETCH TABLE='b' INDEX='b_idx'/>
</JOIN>
<NLJOIN>
<ACCESS TABLE='c' FIRST='TURE'/>
<IXSCAN TABLE='d'/>
</NLJOIN>
</HSJOIN>
解释:
-
a,b进行关联,关键字是让优化器自行选择物理优化阶段的join方式(hashjoin、nljoin等),且a,b谁是外表由优化器自己选择,对于b表指定让其走b_idx索引且通过LPREFETCH高效取出所有索引RID回表方式(这里LPREFETCH指定了数据请求模式)。
-
c,d进行关联,关键字是强制走NLJOIN算法,其中c表是作为外表先执行(first=true),然后告诉d表走索引,但是让优化器自己选择一个高效索引。
-
最后(a,b) hash join (c,d) 是告诉优化器整体上走hash join,自己选择内外表。
-
通过上述hint可以让一个复杂语句中a,b,c,d这四张表按照我们指定的顺序和算法甚至数据请求方式来走执行计划。
这只是最简单通用场景的一种,xml表达能力非常强,DB2对于优化器Hint这块提供了完备的XML Schema定义,非常强大。
MySQL的hint表达能力太弱,只兼容MySQL较为受限。TiDB也可以适当借鉴DB2这种样式,定义自己专有的一套表达机制。