Interesting — looks like the join isn&#x27;t pipelined. The entire right-hand side evaluates synchronously. So it has to wait for the entire right-hand result set before it can evaluate the join operator, instead of streaming it concurrently. I&#x27;m surprised anyone would do it this way in Java, which has good support for concurrency.<p>Edit: Actually the file you linked to was a test file. Hash join code is here [1], and it uses ES&#x27; scrolling feature to incrementally join, though it&#x27;s not pipelined. Not sure scrolling is entirely appropriate for this; it will potentially hold an unpredictable amount of memory on the server end.<p>[1] <a href="https:&#x2F;&#x2F;github.com&#x2F;NLPchina&#x2F;elasticsearch-sql&#x2F;blob&#x2F;5cd6ab63919bd4f366fc721638b31a54e3555b5c&#x2F;src&#x2F;main&#x2F;java&#x2F;org&#x2F;elasticsearch&#x2F;plugin&#x2F;nlpcn&#x2F;HashJoinElasticExecutor.java" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;NLPchina&#x2F;elasticsearch-sql&#x2F;blob&#x2F;5cd6ab639...</a>