modifying main query to query for ranges e.g. from 1999 to 2016

Terms are grouping mechanism. Query logic for them is mostly limited to matching or not matching, which makes you use huge arrays of many possible values in your case.

While year is passably a group (might or might not make sense) the price is most definitely not. Would you shop in store where items are organized in isle by price? Isle with all $1 items, isle with all $2 items, and so on?

Discreet individual values are firmly realm of post meta. Meta also allows much more flexible queries, such as BETWEEN for your use case.

I am not sure why do you consider it “not well optimized”, but it would certainly be better place to start for range queries than terms.