首页/数据/数据库速查/LINDEX / LSET 按下标读写
Redis 命令96 条

LINDEX / LSET 按下标读写

LINDEX 按下标取元素(负数从右数),LSET 按下标改写;越界读取返回 nil,越界写入直接报错。

数据库速查数据更新于 2026-10-13

LINDEX / LSET 是什么

LINDEX 按下标读取列表元素,LSET 按下标改写已存在的元素,两者都支持负数下标(-1 为最后一个元素)。关键要记住 List 的底层是双向链表式结构:头尾操作 O(1),按下标访问中间元素需要逐个走,代价 O(N)。因此越界读取返回 nil 而不报错,越界写入则直接报 index out of range。

基本信息

适用版本Redis 全版本
LINDEX key index按下标取值,O(N);越界返回 nil
LSET key index value按下标改写,O(N);越界报错
负数下标-1 最后一个,-2 倒数第二个,以此类推
头尾操作LPUSH/RPUSH/LPOP/RPOP 均为 O(1)
替代方案随机访问密集场景用 Hash 或 ZSet 存储

典型使用场景

  • 查看队列最新或最早的一条记录:LINDEX key 0 或 -1
  • 修正队列中的单个元素:定位后原地改写,不重建整个列表
  • 任务状态数组的定点更新:小列表上改写某个位置的状态标记
  • 调试列表内容:快速确认某下标上的实际元素
  • 与 LRANGE 配合实现分页读取

示例

示例
RPUSH letters a b c
LINDEX letters 0     # a
LINDEX letters -1    # c
LINDEX letters 99    # nil:越界读取不报错

LSET letters 1 B     # OK,列表变 a B c
LSET letters 9 x     # ERR index out of range:越界写入直接失败

LLEN letters         # 先确认长度,再决定下标是否合法
LRANGE letters 0 -1  # 全量查看,用于核对改写结果

操作代价对照

操作复杂度适用提示
LINDEX 取头尾接近 O(1)获取队首队尾元素的最快做法
LINDEX 取中间O(N)列表越长越慢,避免高频调用
LSET 改写O(N)只能改写已存在的下标,不自动扩容
LRANGE 分页O(S+N)S 为起始偏移,偏移越大越慢
LPOP/RPUSHO(1)队列与栈场景优先使用头尾操作
需要按下标随机访问大量数据时,说明数据结构选错了:List 更适合队列、栈、时间线这类只在两端操作的场景;随机访问密集的业务应改用 Hash(按字段读)或 ZSet(按 score 读)。
LSET 不会自动扩容:对不存在的位置写入会直接报错。批量更新前先用 LLEN 校验长度,或改用 LPUSH/RPUSH 追加,避免脚本中途失败留下半更新状态。

易错点

  • 把 List 当数组频繁做 LINDEX:每次都要链表遍历,长列表上直接变成慢查询
  • LSET 到不存在的位置:报错中断脚本,前面的修改已生效但后续未执行
  • 混淆负数下标含义:-1 是最后一个元素而不是倒数第二个,取值差一位
  • 用 LRANGE 大范围读取替代分页:一次拉回十万条元素,网络与内存压力集中爆发
  • 在大列表上做中间位置插入或改写:O(N) 开销随长度线性增长,应在设计阶段改用 Hash 或 ZSet

数据来源与参考

  • Redis 官方文档: LINDEX
  • Redis 官方文档: LSET

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌