mysql有sin、tan等三角函数,但只接受弧度输入;需用radians()转换度数,如sin(radians(90))=1.0,直接sin(90)是按90弧度计算;注意浮点精度、null处理、索引失效及性能优化。

MySQL里没有TAN和SIN函数?其实是有的,但要注意单位
MySQL原生支持SIN、COS、TAN等三角函数,但它们**只接受弧度(radians)输入**,不是度数。直接传90进去算SIN(90),结果是0.8939966636005579——因为MySQL把它当成了90弧度,不是90度。
- 要算sin(90°),得先转弧度:
SIN(RADIANS(90))→1.0 - 同理,
TAN(RADIANS(45))才是1.0;写成TAN(45)得到的是1.6197751905438615(45弧度≈2578°) -
RADIANS()和DEGREES()是配套的,别只记一半
为什么SIN(0)返回0但SIN(180)不等于0?
这是浮点精度和单位混淆叠加的结果。你以为SIN(180)在算180°的正弦,其实MySQL在算180弧度的正弦——而180弧度 ≈ 10313°,根本不在周期整数倍上。
- 正确写法:
SIN(RADIANS(180))→-1.2246467991473532e-16(接近0,浮点误差) - 如果业务需要严格等于0(比如判断象限),别直接比较
= 0,改用ABS(SIN(RADIANS(x))) - 注意:MySQL的
PI()返回的是近似值,SIN(PI())也不等于0,而是约1.2246e-16
在WHERE或ORDER BY里用TAN要小心除零和定义域
TAN在π/2 + kπ处无定义,对应角度是90°、270°、450°……MySQL遇到这些输入会返回NULL,不是报错。这在过滤或排序时容易漏数据。
- 比如
WHERE TAN(RADIANS(angle)) > 1,当angle = 90时整行被跳过(因为TAN(...)为NULL,NULL > 1结果为UNKNOWN) - 若想排除无效角度,显式加条件:
AND angle % 180 != 90(简单近似,适用于整数度) - 更稳妥的做法是用
IFNULL(TAN(RADIANS(angle)), 0)兜底,但得清楚自己在掩盖什么
性能和替代方案:真有必要在SQL里算三角函数吗?
MySQL的数学函数是标量计算,单行很快,但一旦配合大表扫描或复杂JOIN,SIN/TAN会成为CPU热点——尤其在GIS场景中常被误用来模拟距离或方位。
- 如果只是做坐标转换或球面距离,优先用
ST_DistanceSphere()这类内置空间函数,它们已做优化且考虑地球曲率 - 如果只是前端展示用的角度换算,放到应用层更可控(比如Python用
math.sin(math.radians(x)),JS用Math.sin((x * Math.PI) / 180)) - 确认索引是否失效:对字段套
SIN(RADIANS(col))后无法走索引,别指望它加速查询
三角函数本身不难,难的是意识到MySQL没帮你“猜意图”——它只认弧度,不认“你心里想的90度”。单位、精度、NULL行为、执行位置,四个点串起来才真正落地。











