mysql搜索条件的细微差别造成了巨大的差别,无法让我的思维围绕它

kiayqfof  于 2021-06-24  发布在  Mysql
关注(0)|答案(1)|浏览(263)

我不能说我是mysql的Maven,更多的是新手。但我知道一些基本的性能成本概念。话虽如此,
我有一个大约100万行的用户配置文件表。我想过滤这些值,只返回我感兴趣的内容。
在这些列中,我有纬度和经度列。
为了过滤它的“距离”方面,我创建了一个具有纬度范围和经度范围的任意矩形。
除了“距离”属性之外,我还有一些通用属性,我也用它们过滤:比如年龄、性别等。
我索引了所有的字段,包括纬度和经度。我使用浮动类型的横向和纵向,顺便说一句。
这是一个简单的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次!?!?)
由此产生的select结果差异只有几百(可以理解)。
所以我也试着改变其他的值,看看到底是什么导致了这种情况。我改变周围的纬度值。纬度值似乎对性能没有任何影响。世界跆拳道联盟!
我甚至删除了索引,并尝试了不同的索引变体来解决问题。
还是没有线索。
所以,我更进一步,我把经度值改为-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;




vecaoik1

vecaoik11#

mysql运行一个内部优化器来确定所有查询的执行计划。
查询中的细微变化(在我的例子中)导致优化器提出了一个完全不同的执行计划,因此其中一个值的细微变化会导致结果的巨大差异。
我修复它的方法是改变表的结构(索引等),这样mysql在提出执行计划时会有更好的想法。在我的例子中,修复索引起到了作用。我添加了多列索引,以在某种程度上强制优化器执行特定的路线。
这是我所能做到的,感谢所有评论的帮助。

相关问题