Yihui’s Blog

什么是数据库的游标?

日期:2026-07-11
难度:中等
标签:#面试 #MySQL #游标 #存储过程 #VIP

一句话答案

游标是在存储程序中逐行遍历查询结果集的机制,通过 DECLARE、OPEN、FETCH、CLOSE 控制,适合必须逐行处理的场景,但通常不如集合 SQL 高效。

面试口语版

SQL 天然擅长集合运算,而游标把结果集变成一行一行处理。在 MySQL 存储过程中,先 DECLARE CURSOR FOR SELECT,再 OPEN,循环 FETCH 到变量,处理完成后 CLOSE;通常还要声明 NOT FOUND handler 结束循环。MySQL 游标是只读、不可滚动且 asensitive,不能像应用列表那样随意前后移动。它适合逐行调用复杂规则或无法集合化的维护任务,但大量数据上会产生 row-by-row 开销,应优先尝试 UPDATE JOIN、INSERT SELECT、窗口函数或批处理。

原理拆解

DECLARE done BOOLEAN DEFAULT FALSE;
DECLARE v_id BIGINT;
DECLARE cur CURSOR FOR SELECT id FROM task WHERE status = 'PENDING';
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

OPEN cur;
read_loop: LOOP
  FETCH cur INTO v_id;
  IF done THEN LEAVE read_loop; END IF;
  -- 逐行处理
END LOOP;
CLOSE cur;

关键细节

  • 这里的数据库游标与 Web API 的 Cursor 分页不是同一个概念。
  • 声明顺序是变量/条件、游标、handler;作用域在存储程序块内。
  • 长游标事务可能持有快照或锁,增加 undo 压力和并发风险。

面试官追问

  1. 为什么优先使用集合 SQL?
  2. 游标和 Cursor 分页有什么区别?
  3. 如何处理 FETCH 到末尾?

高分补充

如果确实要逐行处理大数据,通常放到应用侧按主键批量拉取、幂等处理并控制事务边界,比单个超长存储过程更易观测和恢复。

学习清单

  • 能复述 DECLARE、OPEN、FETCH、CLOSE 生命周期。
维护与整理 · Yihui在 GitHub 上编辑

继续阅读

浏览全部文章

SQL与NoSQL有什么区别?MySQL和MongoDB如何选型?实际项目中如何选择?

日期:2026-09-27 标签:#面试 #MySQL #数据库 难度:简单 来源:牛面 MySQL 题库 答案说明:独立整理(站内题目标记为 VIP,未读取会员答案) 一句话答案 MySQL与MongoDB的主要差异在数据模型、事务边界、查询方式和模式演化;按业务访问模式和一致性需求选型。 面试口语版(约 60…

阅读全文