有没有办法优化这个mysql查询?

时间:2014-05-25 19:26:44

标签: mysql sql optimization query-optimization

我有两个名为hg_questionshg_tags的表与hg_question_tag相关联,具有以下结构:

+---------+---------------------+------+-----+---------+-------+
| Field   | Type                | Null | Key | Default | Extra |
+---------+---------------------+------+-----+---------+-------+
| qid     | bigint(20) unsigned | YES  |     | NULL    |       |
| tagid   | bigint(20) unsigned | YES  | MUL | NULL    |       |
| tagname | varchar(50)         | YES  |     | NULL    |       |
+---------+---------------------+------+-----+---------+-------+

我在tagid列的这个表上只有一个索引,以下查询运行速度很慢,因为我的标记号为59440只有464行(这里有很多问题)标签)

SELECT hg_questions.qid,
hg_questions.question,
hg_questions.points,
hg_questions.reward,
hg_questions.answerscount,
hg_questions.created_at,
hg_questions.sections,
hg_questions.answered,
hg_questions.user_id
FROM hg_questions
INNER JOIN hg_question_tag ON hg_question_tag.qid = hg_questions.qid
WHERE hg_question_tag.tagid = 464
ORDER BY points DESC LIMIT 15
OFFSET 0;

在运行此查询的解释时,我得到:

| id | select_type | table           | type   | possible_keys | key     | key_len | ref                              | rows  | Extra                                        |
+----+-------------+-----------------+--------+---------------+---------+---------+----------------------------------+-------+----------------------------------------------+
|  1 | SIMPLE      | hg_question_tag | ref    | tagid         | tagid   | 9       | const                            | 59440 | Using where; Using temporary; Using filesort |
|  1 | SIMPLE      | hg_questions    | eq_ref | PRIMARY       | PRIMARY | 8       | ejaaba_bilal.hg_question_tag.qid |     1 |                                              |
+----+-------------+-----------------+--------+---------------+---------+---------+----------------------------------+-------+----------------------------------------------+

我可以如何优化此查询的任何想法?或者有办法让它更快地运作。


  1. hg_questionspoints
  2. 上有一个索引
  3. 已移除order by points使其工作速度更快,如80%

1 个答案:

答案 0 :(得分:0)

以下是您的查询,在某种程度上进行了简化:

SELECT q.*
FROM hg_questions q INNER JOIN
     hg_question_tag qt
     ON qt.qid = q.qid
WHERE qt.tagid = 464
ORDER BY points DESC
LIMIT 15 OFFSET 0;

您正在同时执行joinorder by。要优化此查询,请尝试在hg_question_tag(tagid, qid)上添加索引。如果标签上没有太多问题,这将有效。

如果许多问题都有标记,那么最好通过问题并选择合适的问题。尝试将查询重写为:

select q.*
from hg_questions q
where exists (select 1 from hg_question_tag qt where qt.qid = q.qid and qt.tagid = 464)
order by points desc
limit 15 offset 0;

保留上述索引并在hg_questions(points, qid)上添加另一个索引。