If all the query planner had to do was decide between index scan types and how to combine them using its wide array of derived nodes, its life would be pretty easy. All the serious complexity in the planner and optimizer relates to joining tables together. Each time another table is added to a list that needs to be joined, the number of possible ways goes up dramatically. If there's, say, three tables to join, you can expect the query plan to consider every possible plan and select the optimal one. But if there are 20 tables to join, there's no possible way it can exhaustively search each join possibility. As there are a variety of techniques available to join each table pair, that further expands the possibilities. The universe of possible plans has to be pruned somehow.
Fundamentally, each way two tables can be joined together gives the same output. The only...