PostgreSQL represents every query internally as a tree structure called the query tree, with each node representing an internal function to execute parts of the query. When joining tables, it uses Join Nodes such as Hash Join, Nested Loop Join, and Merge Join. The choice of Join Node depends on factors like table size, join condition, and whether the output needs to be sorted. Optimizing join performance can involve creating appropriate indexes or limiting the number of rows returned by a query.