有没有办法优化这个mysql查询?
Posted
技术标签:
【中文标题】有没有办法优化这个mysql查询?【英文标题】:Is there any way to optimize this mysql query? 【发布时间】:2014-05-25 19:26:43 【问题描述】:我有两个名为hg_questions
和hg_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_questions
在 points
列上有一个索引
删除了 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;
您正在同时执行join
和order 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 服务器(也许它只需要优化)