首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何优化以下mysql查询

如何优化以下mysql查询
EN

Stack Overflow用户
提问于 2017-03-31 14:39:44
回答 3查看 42关注 0票数 0

我在mysql查询中遇到了问题。查询如下。

代码语言:javascript
复制
SELECT *  
FROM group 
WHERE  (level IN (3,4,5,6) AND  last_time BETWEEN  0 AND 3) 
OR     (level IN (4,5,6,7) AND  last_time BETWEEN  0 AND 6);

我如何优化查询,也许可以删除OR单词。谢谢。

此外,查询还可以像下面这样进行扩展。

代码语言:javascript
复制
SELECT *  
    FROM group 
    WHERE  (level IN (3,4,5,6) AND  last_time BETWEEN  0 AND 3) 
    OR     (level IN (4,5,6,7) AND  last_time BETWEEN  0 AND 6)
    OR     ... ;

谁能解释一下解决方案的思路,非常感谢。

EN

回答 3

Stack Overflow用户

发布于 2017-03-31 15:16:15

按原样查询看起来很好。有时,您需要满足一个另一个条件。优化器的工作是找到执行查询的最佳方法。

您可以尝试帮助优化器,但实际上这不是必需的,所以只有在确实有性能问题时才这样做。

您的查询可以写成

代码语言:javascript
复制
SELECT *  
FROM group 
WHERE  (level = 3 AND  last_time BETWEEN  0 AND 3) 
OR     (level IN (4,5,6,7) AND  last_time BETWEEN  0 AND 6);

因为有重叠的标准,但我怀疑这对优化器有多大帮助。

您还可以执行以下操作:

代码语言:javascript
复制
SELECT *  
FROM group 
WHERE Level in (3,4,5,6,7) 
AND last_time BETWEEN 0 AND 6
AND 
(
  (level IN (3,4,5,6) AND  last_time BETWEEN  0 AND 3) 
OR
  (level IN (4,5,6,7) AND  last_time BETWEEN  0 AND 6)
);

因此,您应该首先列出所有有问题的值(没有条件要求level不在3-7之间,也没有条件要求last_time不在0-6范围内)。只有这样,才能列出单个条件。这可能对优化器有帮助,也可能没有帮助。

在任何情况下,您都应该在level + last_time上有一个复合索引。使用此索引还是执行全表扫描更快取决于数据,但无论如何您都应该提供这样的索引。

票数 1
EN

Stack Overflow用户

发布于 2017-03-31 18:07:41

通常,最快的解决方案是将其拆分成多个UNIONed查询。然后,每个较小的查询都可以有效地使用索引。

代码语言:javascript
复制
SELECT *  
FROM group 
WHERE  (level IN (3,4,5,6) AND  last_time BETWEEN  0 AND 3) 
UNION
SELECT *  
FROM group 
WHERE  (level IN (4,5,6,7) AND  last_time BETWEEN  0 AND 6);
票数 0
EN

Stack Overflow用户

发布于 2017-03-31 18:25:14

让我们来看看MySQL是否足够智能来优化OR:

代码语言:javascript
复制
mysql> explain splain select * from seqid in (1,2,3) or id in (4,5,6);
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-----------------------+
| id | select_type | table | partitions | type  | possible_keys | key     | key_len | ref  | rows | filtered | Extra                 |
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-----------------------+
|  1 | SIMPLE      | seq   | NULL       | range | PRIMARY       | PRIMARY | 4       | NULL |    6 |   100.00 | Using index condition |
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-----------------------+

"seq“是一个包含1M个整数的表。

嗯,MySQL对OR进行了优化。正如您所期望的那样,它使用了索引。不需要进一步调整查询。

我建议您检查查询的EXPLAIN,以验证您的MySQL是否正确地优化了它。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43134052

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档