MYSQL搜索条件的微小差异会产生巨大的差异,无法绕过它

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MYSQL搜索条件的微小差异会产生巨大的差异,无法绕过它相关的知识,希望对你有一定的参考价值。

我不能说我是mysql的专家,更多的是新手方面。但我知道一些基本的性能成本概念。话说回来,

我有一个约100万行的用户配置文件表。我想过滤这些值,只回到我感兴趣的地方。

在列中,我有纬度和经度列。

为了过滤它的“距离”方面,我创建了一个具有纬度范围和经度范围的任意矩形。

除了“距离”属性,我还有一些我也可以过滤的通用属性:如年龄,性别等。

我索引了所有字段,包括纬度和经度。我使用FLOAT类型用于lat和long,BTW。

所以,这是一个简单的SELECT查询,具有多个属性,如此,

SELECT user_id FROM profiles WHERE gender = 1 AND birthday BETWEEN '1980-01-27' AND '1988-01-27' AND longitude BETWEEN -105 AND -103.6 AND latitude BETWEEN 35 AND 40

************这是最奇怪的事情**************

当我使用经度的滤波器值(例如-105和-103.6)(以及其他属性)进行测试时,查询运行相对较快(49ms)。但是当我将经度值更改为-105到-103.5(0.1差异!)时,查询需要493ms。 (10倍!?!?!?!)

得到的选择结果差异只有几百(可以理解)。


所以我也尝试改变其他值,看看是什么造成了这个。我改变了纬度值。纬度值似乎对性能没有任何影响。 WTF!

我甚至删除索引,并尝试不同的索引变化只是为了解决问题。

仍然不是一个线索。

所以,我深入研究这一点,我将经度值更改为-105到-103.597之间。 -103.597需要49ms,而-105和-103.596需要526ms。

0.001差异不可能在查询性能上产生那种差异。我错过了什么?

我正在使用InnoDB,mysql版本5.7.19,顺便说一句。

表模式,

CREATE TABLE `profiles` (
  `user_id` varchar(8) NOT NULL DEFAULT '',
  `gender` tinyint(1) NOT NULL DEFAULT '0',
  `orientation` tinyint(1) NOT NULL DEFAULT '0',
  `birthday` date NOT NULL DEFAULT '2000-01-01',
  `height` tinyint(2) NOT NULL DEFAULT '0',
  `ethnicity` int(2) NOT NULL DEFAULT '0',
  `latitude` float NOT NULL DEFAULT '0',
  `longitude` float NOT NULL DEFAULT '0',
  PRIMARY KEY (`user_id`),
  KEY `gender` (`gender`),
  KEY `birthday` (`birthday`),
  KEY `longitude` (`longitude`),
  KEY `latitude` (`latitude`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

enter image description here

enter image description here

enter image description here


enter image description here

答案

MySQL运行内部优化器来确定所有查询的执行计划。

查询中的细微变化(在我的情况下)导致优化器提出了完全不同的执行计划,因此其中一个值稍有变化的结果差别很大。

我修复它的方法是改变表的结构,(索引等),以便MySQL在提出执行计划时有更好的想法。就我而言,修复索引就可以了。我添加了多列索引来强制优化器走一条路线。

就这一点而言,感谢所有评论者的帮助。

以上是关于MYSQL搜索条件的微小差异会产生巨大的差异,无法绕过它的主要内容,如果未能解决你的问题,请参考以下文章

18 | 为什么这些SQL语句逻辑相同,性能却差异巨大?

18 | 为什么这些SQL语句逻辑相同,性能却差异巨大?

查询速度的巨大差异

最全解释Mysql 的join中on与where 过滤条件差异

两个相似查询的巨大速度差异(MySQL ORDER 子句)

mysql 执行时间的巨大差异:最小 2 秒 - 最大 120 秒