order by weight() * rand() - не то, так как элементы с меньшими весами при большом количестве элементов выпадают с очень маленькой вероятностью.
Если нужно выбрать один элемент, можно выгрузить все-все веса из таблицы, посчитать их сумму, выбрать случайное число из промежутка от 1 до суммы, идти по массиву и суммировать элементы, нужный элемент будет тогда, когда сумма достигнет случайного число.
А если нужно несколько разных элементов? Можно конечно вычесть из суммы уже выбранный элемент, удалить его из массива и повторить операцию, и так для каждого, но это медленно.
Есть у кого-нибудь ещё варианты?