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

Posted

技术标签:

【中文标题】有没有办法优化这个mysql查询?【英文标题】:Is there any way to optimize this mysql query? 【发布时间】:2014-05-25 19:26:43 【问题描述】:

我有两个名为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 |                                              |
+----+-------------+-----------------+--------+---------------+---------+---------+----------------------------------+-------+----------------------------------------------+

有什么想法可以优化这个查询吗?或者有办法让它更快地工作。


    hg_questionspoints 列上有一个索引 删除了 order by points 使其工作速度提高了 80%

【问题讨论】:

您能否也发布 hg_questions 和 hg_tags 表,以便我们确定它们的外观? 好的,我现在就发。 @Bilal,尝试在点上创建索引。 @Vlad 是的,我有一个积分索引。 【参考方案1】:

这是您的查询,在某种程度上简化了:

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)上放置另一个索引。

【讨论】:

“不工作”我认为大多数方法的性能与您的原始查询相似? 您的解决方案给了我很多最差的性能,事实证明,仅查询标签(不加入问题)并在循环中获取相关问题提供了更好的性能。 ejaaba.com/label/464 @Bilal 。 . .我认为即使在创建了所述索引之后也是如此。 是的,我创建了所有索引并使用了您提供的查询,mysql 服务器消失了

以上是关于有没有办法优化这个mysql查询?的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法优化这个查询

如何优化Mysql千万级快速分页

mysql百万数据分页查询4秒,求教怎么优化

我的 MySQL 查询似乎破坏了 MySQL 服务器(也许它只需要优化)

在 MySQL 查询中使用 OR 时,有没有办法使用索引来避免文件排序?

MySQL查询优化