mysql中BETWEEN操作符进行范围查询的使用

来源:这里教程网 时间:2026-02-28 20:39:05 作者:

MySQL中
BETWEEN
是闭区间,包含边界值

很多人误以为

BETWEEN
是“左开右闭”或受NULL影响行为异常,其实它严格等价于
col >= low AND col ,两端都包含。只要<code>low
high
可比较、类型兼容,且不为
NULL
,结果就确定。

常见错误现象:

写成
WHERE id BETWEEN 10 AND 5
——MySQL会自动交换顺序,仍返回
5 ,但语义混乱,应避免
WHERE date_col BETWEEN '2023-01-01' AND '2023-01-01'
查单日数据——它能命中当天00:00:00,但漏掉当天其他时间点(除非
date_col
DATE
类型)
TEXT
JSON
列直接用
BETWEEN
——可能触发隐式转换或全表扫描,性能差

BETWEEN
>=
/
在索引使用上完全等价

优化器对

BETWEEN
的处理和显式写
col >= a AND col 一样,只要列上有索引,且条件不含函数或表达式,就能走范围扫描(<code>type: range
)。

实操建议:

检查执行计划:
EXPLAIN SELECT * FROM orders WHERE created_at BETWEEN '2024-01-01' AND '2024-01-31';
确认
key
字段非
NULL
rows
量级合理
如果
created_at
DATETIME
,想查2024年1月整月,必须写成
BETWEEN '2024-01-01 00:00:00' AND '2024-01-31 23:59:59'
,或更安全地用
>= '2024-01-01' AND 
复合索引中,
BETWEEN
只能用于最左前缀的连续部分。例如索引
(a, b, c)
WHERE a = 1 AND b BETWEEN 2 AND 4
可用索引,但
WHERE a > 1 AND c BETWEEN 10 AND 20
无法利用
c
的索引

字符串和日期用
BETWEEN
要特别注意排序规则和精度

字符串比较依赖当前列的

collation
,比如
utf8mb4_0900_as_cs
区分大小写和重音,而
utf8mb4_general_ci
不区分。这直接影响
BETWEEN 'a' AND 'z'
是否包含
'Z'
'é'

日期时间类型更要小心:

DATE
列:直接
BETWEEN '2024-01-01' AND '2024-01-01'
没问题,精确到日
DATETIME
TIMESTAMP
列:同上写法只匹配
00:00:00
这一秒,几乎必然为空
时区问题:
TIMESTAMP
存的是UTC,但
BETWEEN
字面量按会话时区解析。例如会话在
+08:00
BETWEEN '2024-01-01' AND '2024-01-01'
实际查的是UTC的
2023-12-31 16:00:00
2024-01-01 16:00:00

遇到
NULL
BETWEEN
直接返回
UNKNOWN

这是SQL三值逻辑的体现:

NULL BETWEEN 1 AND 10
既不是
TRUE
也不是
FALSE
,而是
UNKNOWN
,所以该行不会出现在查询结果中——和
WHERE
子句里所有
UNKNOWN
都被过滤掉一致。

这意味着:

WHERE col BETWEEN 1 AND 10
等价于
WHERE col >= 1 AND col ,天然排除<code>NULL
如果业务需要包含
NULL
,必须显式加判断:
WHERE (col BETWEEN 1 AND 10) OR col IS NULL
不要依赖
BETWEEN
来“过滤掉NULL”,它只是顺带不匹配;真正想排除
NULL
,还是明确写
IS NOT NULL
更清晰

边界值类型隐式转换、时区上下文、索引生效前提,这三个地方最容易被忽略。写完

BETWEEN
语句后,务必用
EXPLAIN
看执行计划,并用
SELECT ... LIMIT 5
验证实际返回的数据是否符合预期时间/字符范围。

相关推荐