web-dev-qa-db-ja.com

mysqlwikipediaデータベースでウィキペディアの記事のクエリ最適化を取得します

ウィキペディアデータベースをローカルのMySQLデータベースにインポートし、ウィキページをフェッチするクエリを作成しました。

私の質問は次のとおりです:

SELECT
  p.page_title,
  p.page_id,
  t.id,
  text.old_text
FROM wikipedia_en.page p
  INNER JOIN wikipedia_en.categorylinks cl
         ON  cl.cl_from = p.page_id AND cl.cl_type = 'page'
         AND p.page_namespace = 0
         AND p.page_is_redirect = 0
  INNER JOIN wikipedia_en.revision ON revision.rev_id = p.page_latest
  INNER JOIN wikipedia_en.text ON text.old_id = revision.rev_text_id

   -- filter out pages with no topic 
  INNER JOIN topics.topics t  ON cl.cl_to = t.topic
LIMIT 520000, 10000;

LIMITオフセットが0から始まる場合、クエリには約2秒かかりますが、オフセットが大きくなると(たとえば、520000)、クエリの実行にかなりの時間がかかります(たとえば、520000のオフセットの場合、約4分かかります)。

これがクエリExplainPlanです:

+----+-------------+----------+--------+------------------------------------------------+------------+---------+-----------------------------------+--------+--------------------------+
| id | select_type | table    | type   | possible_keys                                  | key        | key_len | ref                               | rows   | Extra                    |
+----+-------------+----------+--------+------------------------------------------------+------------+---------+-----------------------------------+--------+--------------------------+
|  1 | SIMPLE      | t        | ALL    | topics_topic_index                             | NULL       | NULL    | NULL                              | 141413 |                          |
|  1 | SIMPLE      | cl       | ref    | PRIMARY,cl_timestamp,cl_sortkey                | cl_sortkey | 258     | topics.t.topic,const              |     14 | Using where; Using index |
|  1 | SIMPLE      | p        | eq_ref | PRIMARY,name_title,page_redirect_namespace_len | PRIMARY    | 4       | wikipedia_en.cl.cl_from           |      1 | Using where              |
|  1 | SIMPLE      | revision | eq_ref | PRIMARY                                        | PRIMARY    | 4       | wikipedia_en.p.page_latest        |      1 |                          |
|  1 | SIMPLE      | text     | eq_ref | PRIMARY                                        | PRIMARY    | 4       | wikipedia_en.revision.rev_text_id |      1 |                          |
+----+-------------+----------+--------+------------------------------------------------+------------+---------+-----------------------------------+--------+--------------------------+

サブクエリまたは一時テーブルを使用してこのクエリを最適化する方法があるかどうかを尋ねています。

1
Yacine al

OFFSETは行を見つける必要がありますが、スキップします。 「中断したところを覚えておく」ことができれば、パフォーマンスが大幅に向上する可能性があります。

しかし、クエリにはさらに悪い問題があります。 ORDER BYがないため、オプティマイザーは任意の順序で行を自由に提供でき、それによって行の欠落や重複が発生します。

ORDER BYを追加した場合でも、テーブルが追加または削除されている場合、OFFSETは行の欠落または重複を引き起こす可能性があります。

この問題について私の blog を読んでから、クエリを最初からやり直してください。

3
Rick James