32 bit virtual address space was a bit of a bad idea.
Intel basically goofed by making the address space on i386 32-bits wide. This required, in practice, for every process to use a dedicated virtual-to-physical address map, and for the caches to be using physical memory addressing. This meant that the expensive address translation was on the critical path to the caches: all addresses had to be translated before hitting the cache. This was - and still is - extremely die-space and power hungry. Fast logic means high power use.
If Intel had the foresight to use 64-bit virtual address space, perhaps limited to say 30 bits on i386 as an implementation limitation, but later expanded, then the caches could have used virtual addressing. This would move address translation to the bottom, just before hitting DRAM. Since DRAM access is relatively slow, the address translation overhead would have been negligible, and could have been implemented using slower logic, and more of it - to accommodate larger translation tables at the same cost in power and die area.
The 32-bit per-process address space of x86 had a rather big performance impact in terms of achievable clock speeds, power envelope, process switching overhead, complexity of parts of OS kernel, etc. Having the architecture deal with 64-bit virtual addresses internally, and only needing to check protection buffers on cache accesses, vs. doing address translation, would have probably avoided the fiasco known as Netburst deeply-pipelined architecture of P4.
Of course, back when the 386 was first introduced, there was no need for more than 32 bits of external address bus, and the 386sx has just 24 external address bits. But the fact that the virtual address space was just 32 bits, and caches had to use physical addresses, turned out to have consequences that last until this day, and result in higher power use, higher R&D costs of CPU development, and so on.