0

keywordskeywordとを持つテーブルがありますweight。私の目標は、ランダムに 1 つを選択することですkeywordが、そのweight(確率) を考慮することです。私はこれを解決する2つの方法を見つけました.後者の方がよりエレガントです(そしてリソースの消費が少なくなります)-しかし、私はそれを実行することができません. 自分自身を参照してください。

テーブルとレコード:

CREATE TABLE IF NOT EXISTS `keywords` (
  `keyword` varchar(100) COLLATE utf8_bin NOT NULL,
  `weight` int(11) NOT NULL,
  UNIQUE KEY `keywords` (`keyword`),
  KEY `rate` (`weight`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

INSERT INTO `keywords` (`keyword`, `weight`) VALUES
('google', 50),
('microsoft', 20),
('apple', 10),
('yahoo', 5),
('bing', 5),
('xing', 5),
('cool', 5);

クエリ 1

より多くのリソースを消費します。私は 5,000 件以上のレコードに取り組んでいます。ソースは、rand() を使用したこの MySQL クエリが約 3 分の 1 の時間で結果を返さないのはなぜですか? :

SELECT *  FROM `keywords` ORDER BY -LOG(1.0 - RAND()) / weight LIMIT 1

クエリ 2

重みを に合計します@weight_sum。その範囲内の数値に設定@weight_pointします。RAND()すべてのレコードをループし、現在のから減算weight@weight_posて設定します。まで。その後、それを保持します。ソースはT-SQL のランダム加重選択です@keywordkeywords.keyword@weight_pos < 0keyword

SET @keyword = 0;
SET @weight_sum = (SELECT SUM(weight) FROM keywords);
SET @rand = RAND();
SET @weight_point = ROUND(((@weight_sum - 1) * @rand + 1), 0);
SET @weight_pos = @weight_point;

SELECT
    keyword,
    weight,

    @keyword:=CASE
        WHEN @weight_pos < 0 THEN @keyword
        ELSE keyword
    END AS test,

    (@weight_pos:=(@weight_pos - weight)) AS curr_weight,
    @weight_point,
    @keyword,
    @weight_pos,
    @rand,
    @weight_sum
FROM
    keywords;

ここでphpmyadminの結果を参照してくださいhttp://postimg.org/image/stgpd776f/

phpmyadmin

私の質問

の値を取得するにはどうすればよいです@keywordか、またはtest列が最後に保持するものは何ですか? 後に追加してSELECT @keywordも何も変わりません。

4

1 に答える 1