mysql 使用游标

这是我使用mysql游标写的一个存储过程。当然只是初识mysql 的游标

DELIMITER $$

USE `0801`$$

DROP PROCEDURE IF EXISTS `SB_MOLECULE_SPECIES_URL`$$

CREATE DEFINER=`scommerce`@`%` PROCEDURE `SB_MOLECULE_SPECIES_URL`()

BEGIN
#声明变量并附默认值;
DECLARE siteId CHAR(32) DEFAULT 'e61244a8e61244a8f8108745f8108745';
DECLARE createBy CHAR(32) DEFAULT 'f1ecf7eace1511e1968100242cbeedaa';
DECLARE pageId CHAR(32) DEFAULT '7bf8ecf331f111e2a063001e6745fd58';

DECLARE sourceName VARCHAR(255) DEFAULT '';
DECLARE targetName VARCHAR(255) DEFAULT '';
DECLARE done INT DEFAULT 0; 
#声明游标
DECLARE mycur CURSOR FOR SELECT source_name ,target_name FROM sc_coj_edge WHERE conjunction_id='870b05eb5e8811e39c86f23c9169b4e1' LIMIT 1;
#如果没有找到数据(有的人此处不写not found 会写 SQLSTATE '02000')则将变量done的值置为1;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
#open 打开游标
OPEN mycur;
#开始循环游标
emp_loop:LOOP
#FETCH 获取游标当前指针的记录,并传给指定变量列表,注意变量数必须与MySQL游标返回的字段数一致,要获得多行数据,使用循环语句去执行FETCH
FETCH mycur INTO sourceName,targetName;
SELECT done;

#如果变量done = 1 则跳出循环
IF done = 1 THEN
LEAVE emp_loop;
ELSE
#此处根据需要进行相应的表操作;

END IF;
#结束循环
END LOOP emp_loop;
#关闭游标
CLOSE mycur;
    END$$


DELIMITER ;

<think>我们正在讨论MySQL中基于游标的分页查询。基于游标的分页(也称为键集分页)是一种高效的分页技术,特别适用于大数据集和深度分页的场景。它通过记住上一页最后一项的位置(即游标)来获取下一页的数据,避免了传统分页(如LIMIToffset,size)在深度分页时的性能问题。在基于游标的分页中,我们通常使用一个或多个有序列(如时间戳、ID等)作为游标。假设我们有一个表`orders`,其中包含`id`(主键)、`order_date`(订单日期)和`amount`(订单金额)等列。我们想要按订单日期(降序)和ID(升序)进行分页。步骤:1.确定游标列:通常选择唯一且有序的列,例如主键。如果主键不能完全满足排序需求,可能需要组合多个列(例如,订单日期和ID)。2.在查询中,我们使用WHERE条件来指定从游标之后(或之前,取决于排序方向)开始获取数据。3.使用ORDERBY确保顺序一致。示例:假设我们想要按`order_dateDESC,idASC`排序,每页10条记录。第一页查询(没有游标):```sqlSELECTid,order_date,amountFROMordersORDERBYorder_dateDESC,idASCLIMIT10;```假设第一页的最后一条记录的`order_date`为'2023-10-1012:00:00',`id`为100。那么第二页的查询应该从这条记录之后开始。第二页查询:```sqlSELECTid,order_date,amountFROMordersWHERE(order_date<'2023-10-1012:00:00')OR(order_date='2023-10-1012:00:00'ANDid>100)ORDERBYorder_dateDESC,idASCLIMIT10;```解释:-由于我们是按`order_date`降序排列,所以下一页的订单日期应该小于上一页最后一条的订单日期(因为日期越早越小)。-或者,当订单日期相等时,我们要求ID大于上一页最后一条的ID(因为我们按ID升序,所以下一页的ID应该更大)。注意:在构建条件时,需要根据排序方向调整不等号的方向。如果排序是升序(ASC),则下一页的条件应该是大于(>);如果是降序(DESC),则条件应该是小于(<)。在MySQL中,我们可以使用多个条件组合来处理多列游标。另外,基于游标的分页通常需要客户端传递上一页最后一条记录的游标值(即排序字段的值)。因此,在返回每一页数据时,需要将最后一行的游标值返回给客户端,以便客户端请求下一页时提供。关于性能:为了确保查询效率,我们需要在排序字段上建立合适的索引。例如,对于上面的查询,可以创建索引:`(order_dateDESC,idASC)`。现在,根据要求生成相关问题。</think>### MySQL 游标分页查询实现 在 MySQL 中,基于游标的分页(Cursor-based Pagination)通过**记录位置标识**而非传统 `LIMIT offset` 实现高效分页,特别适合大数据量场景。核心原理是利用有序列的唯一值作为定位点[^1]。 #### 基础实现示例 假设有订单表 `orders`,按创建时间分页: ```sql -- 第一页(无游标) SELECT order_id, created_at, amount FROM orders WHERE created_at >= '2023-01-01' ORDER BY created_at ASC, order_id ASC -- 必须包含唯一列保证顺序 LIMIT 10; -- 下一页(使用上一页最后一条记录的游标值) SELECT order_id, created_at, amount FROM orders WHERE created_at > '2023-05-20 14:30:00' -- 上一页最后记录的 created_at OR (created_at = '2023-05-20 14:30:00' AND order_id > 10025) -- 处理相同时间点 ORDER BY created_at ASC, order_id ASC LIMIT 10; ``` #### 多列游标分页[^2] 当需要多列排序时(如按金额+时间): ```sql SELECT order_id, created_at, amount FROM orders WHERE (amount, created_at, order_id) > (50.00, '2023-05-20', 10025) -- 元组比较 ORDER BY amount DESC, created_at ASC, order_id ASC LIMIT 10; ``` #### 关键要点 1. **排序要求** - 必须包含至少一个唯一列(如主键)作为最终排序条件 - 排序顺序需与 WHERE 条件中的比较方向一致 2. **性能优势** ```mermaid graph LR A[传统分页] -->|深分页扫描| B(offset+N行) C[游标分页] -->|索引定位| D(直接目标位置) ``` 3. **索引优化** 需为所有排序字段创建复合索引: ```sql CREATE INDEX idx_pagination ON orders (amount DESC, created_at ASC, order_id ASC); ``` #### ORM 实现参考 在 ORM 中(如 Django),可通过封装查询条件实现: ```python # 伪代码示例 def get_next_page(last_record): return Orders.objects.filter( Q(amount__lt=last_record.amount) | Q(amount=last_record.amount, created_at__gt=last_record.created_at) | Q(amount=last_record.amount, created_at=last_record.created_at, id__gt=last_record.id) ).order_by('-amount', 'created_at', 'id')[:10] ``` [^3] ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值