IS the utxo set stored independently from the block set?
Yes. It's called
chainstate, few call it UTXO set.
how does bitcoin search the db for a given utxo to verify a transaction is legitimate if it just stores the blocks?
By access
chainstate, not access blocks
Okay thanks. This seems like something that could be easily optimised no? Instead of having a tonne of duplicated data that is both in the utxo db and blocks db. You could have each block, and each tx that tries to spend utxo's (instead of referencing a previous tx hash), references a block number and position in the block of the tx he is trying to spend. then the client finds the tx and position of the utxo inside the tx and checks the lockscript/unlockscript.