优化合并联接

Optimizing merge join

阅读这篇文章https://bertwagner.com/posts/visualizing-merge-join-internals-and-understanding-their-implications/

有这样的词组:

“如果优化器向上游合并连接添加了排序,可能值得研究是否可以对该数据进行预排序,这样 SQL 服务器就不需要对其进行排序通常,这就像将包含的索引列重新定义为键列一样简单 - 如果您将其添加为索引中的最后一个键列,那么回归影响通常很小,但您可以允许 SQL 服务器使用合并联接而不需要任何额外的排序。"

我不明白。作者提议将额外的列(按 sql 服务器本身排序的列)作为最后一个添加到现有索引中?据我了解,索引是从 1 列到最后排序的。

table 列为“number”(int)、“letter”(varchar) 的索引(“number”、“letter”)如

那么索引中存在“字母”列是如何避免服务器对其进行排序的麻烦的呢?

合并联接只能合并到已根据联接谓词(向前或向后)排序的数据流。

如果连接谓词包含两列 (number & letter),但只有 number 上有索引,引擎将无法将该索引用作“预排序”数据流的来源。如果引擎决定在这种情况下进行合并,您会注意到计划将在合并运算符的下游包含一个额外的运算符“排序”。如果排序很昂贵,这可能效率不高。

作者的意思是,如果您看到这样的案例,那么您可以通过向其中添加列 letter 来探索更改现有索引的可能性。在这个新场景中,引擎将能够直接使用这个索引作为预排序的数据流,而不需要下游额外的“排序”运算符。

但是,更改索引可能很棘手。也许提高这个查询的性能会降低另一个更重要的查询的性能。确保您理解其中的含义。