Even a clever hash function is vulnerable to bad expected-case performance.
Any fixed hash function has some set of keys that will result in a pile up.
We can use randomness to get around this, mostly.
Resulting algorithm is the only truly provably good hashing scheme (uniform hashing is a crock), but I don't think anyone uses it in practice.