1

このクエリは完了するまでに 1 分以上かかります:

SELECT keyword, count(*) as 'Number of Occurences'
    FROM movie_keyword
    JOIN
    keyword
    ON keyword.`id` = movie_keyword.`keyword_id`
    GROUP BY keyword
    ORDER BY count(*) DESC
    LIMIT 5

すべてのキーワードには ID が関連付けられています (keyword_id 列)。そして、その ID を使用して、キーワード テーブルから実際のキーワードを検索します。

movie_keyword には 280 万行あります

キーワードは 127,000 を持っています

ただし、最も使用されている keyword_id だけを返すのに 1 秒しかかかりません。

SELECT keyword_id, count(*)
    FROM movie_keyword
    GROUP BY keyword_id
    ORDER BY count(*) DESC
    LIMIT 5

これを行うより効率的な方法はありますか?

EXPLAIN による出力:

1   SIMPLE  keyword ALL PRIMARY NULL    NULL    NULL    125405  Using temporary; Using filesort
1   SIMPLE  movie_keyword   ref idx_keywordid   idx_keywordid   4   imdb.keyword.id 28  Using index

構造:

CREATE TABLE `movie_keyword` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `movie_id` int(11) NOT NULL,
  `keyword_id` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_mid` (`movie_id`),
  KEY `idx_keywordid` (`keyword_id`),
  KEY `keyword_ix` (`keyword_id`),
  CONSTRAINT `movie_keyword_keyword_id_exists` FOREIGN KEY (`keyword_id`) REFERENCES `keyword` (`id`),
  CONSTRAINT `movie_keyword_movie_id_exists` FOREIGN KEY (`movie_id`) REFERENCES `title` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4256379 DEFAULT CHARSET=latin1;

CREATE TABLE `keyword` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `keyword` text NOT NULL,
  `phonetic_code` varchar(5) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_keyword` (`keyword`(5)),
  KEY `idx_pcode` (`phonetic_code`),
  KEY `keyword_ix` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=127044 DEFAULT CHARSET=latin1;
4

3 に答える 3

1

テストされていませんが、私の意見では動作し、大幅に高速になるはずです。ただし、mysql のサブクエリで制限を使用できるかどうかはよくわかりませんが、それを回避する方法は他にもあります。

SELECT keyword, count(*) as 'Number of Occurences'
    FROM movie_keyword
    JOIN
    keyword
    ON keyword.`id` = movie_keyword.`keyword_id`
    WHERE movie_keyword.keyword_id IN (
        SELECT keyword_id
        FROM movie_keyword
        GROUP BY keyword
        ORDER BY count(*) DESC    
        LIMIT 5
    )
    GROUP BY keyword
    ORDER BY count(*) DESC;

movie_keyword の 280 万のエントリすべてをキーワードで結合するのではなく、実際に一致するものだけを結合するわけではないため、これはより高速になるはずです。これはかなり少ないと思います。

編集mysql は、実行する必要があるサブクエリ内の制限をサポートしていないため

SELECT keyword_id
FROM movie_keyword
GROUP BY keyword
ORDER BY count(*) DESC    
LIMIT 5;

最初に結果を取得した後、2 番目のクエリを実行します

SELECT keyword, count(*) as 'Number of Occurences'
    FROM movie_keyword
    JOIN
    keyword
    ON keyword.`id` = movie_keyword.`keyword_id`
    WHERE movie_keyword.keyword_id IN (RESULTS_FROM_FIRST_QUERY_SEPARATED_BY_COMMAS)
    GROUP BY keyword
    ORDER BY count(*) DESC;

RESULTS_FROM_FIRST_QUERY_SEPARATED_BY_COMMAS使用している言語に関係なく、プログラムで適切な値に置き換えます

于 2012-10-09T03:17:50.300 に答える
0

クエリは問題ないようですが、構造はそうではないと思います。列にインデックスを付けてみてください

keyword.id

試す、

CREATE INDEX keyword_ix ON keyword (id);

また

ALTER TABLE keyword ADD INDEX keyword_ix (id);

テーブルの構造を投稿できれば、はるかに優れていkeywordますMovie_keyword。主テーブルと参照テーブルはどちらですか?

SELECT keyword, count(movie_keyword.id) as 'Number of Occurences'
FROM movie_keyword
     INNER JOIN  keyword
           ON keyword.`id` = movie_keyword.`keyword_id`
GROUP BY keyword
ORDER BY 'Number of Occurences' DESC
LIMIT 5
于 2012-10-09T02:22:50.557 に答える