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;
MySQL运行内部优化器来确定所有查询的执行计划。
查询中的细微变化(在我的情况下)导致优化器提出了完全不同的执行计划,因此其中一个值稍有变化的结果差别很大。
我修复它的方法是改变表的结构,(索引等),以便MySQL在提出执行计划时有更好的想法。就我而言,修复索引就可以了。我添加了多列索引来强制优化器走一条路线。
就这一点而言,感谢所有评论者的帮助。
以上是关于MYSQL搜索条件的微小差异会产生巨大的差异,无法绕过它的主要内容,如果未能解决你的问题,请参考以下文章