游标的慎用和索引(Index)的使用

本文探讨了在数据库操作中如何合理使用游标与索引来提升查询效率。通过避免不当使用游标,采用更高效的索引策略,可以显著改善数据库性能。

1.1 游标(Cursor)的慎用

游标提供了对特定集合中逐行扫描的手段,一般使用游标逐行遍历数据,根据取出的数据不同条件进行不同的操作。尤其对多表和大表定义的游标(大的数据集合)循环很容易使程序进入一个漫长的等待甚至死机。而如果不同的条件改成用不同的UPDATE语句往往可以得到比较好的效率提高。示例如下:

Declare Mycursor cursor for select  count_no from COUNT

	Open Mycursor

	Fetch Mycursor into @vcount_no

	While (@@sqlstatus=0)

Begin

	If  @vcount_no=’’  条件1

	操作1

If  @vcount_no=’’  条件2

			操作2

			。。。

	Fetch Mycursor into @vcount_no

End

。。。

。。。

	改为

Update COUNT set  操作1 for 条件1

Update COUNT set  操作2 for 条件2

。。。

。。。


在有些场合,有时也非得使用游标,此时也可考虑将符合条件的数据行转入临时表中,再对临时表定义游标进行操作,可时性能得到明显提高。示例如下:


Create #tmp   /* 定义临时表 */

(      字段1

       字段2

       。。。

       )

Insert into #tmp select * from TOTAL where 

Declare Mycursor cursor for select * from #tmp

/*对临时表定义游标*/

1.2 索引(Index)的使用原则

创建索引一般有以下两个目的:维护被索引列的唯一性和提供快速访问表中数据的策略。大型数据库有两种索引即簇索引和非簇索引,一个没有簇索引的表是按堆结构存储数据,所有的数据均添加在表的尾部,而建立了簇索引的表,其数据在物理上会按照簇索引键的顺序存储,一个表只允许有一个簇索引,因此,根据B树结构,可以理解添加任何一种索引均能提高按索引列查询的速度,但会降低插入、更新、删除操作的性能,尤其是当填充因子(Fill Factor)较大时。所以对索引较多的表进行频繁的插入、更新、删除操作,建表和索引时因设置较小的填充因子,以便在各数据页中留下较多的自由空间,减少页分割及重新组织的工作。

不要随便乱建索引索引会消耗大量空间并严重降低插,删,(相当的)改操作的性能

不要随便用聚合索引,比如总是把聚合索引缺省地用在主key上。一个表只能有一个聚合索引,要把这好钢用在刀刃上。详见后述  

UNIQUE是非常重要的信息,如果能加一定要加上。千万不要以为identity之类的列上建索引, sql server会自动地认为是UNIQUE

索引建议总是建议造非聚合索引,什么时候用聚合索引这得由你自己来决定。如果符合下列条件之一,你应该考虑用聚合索引

l          结果集很大

l          检索条件中有“范围”条件,即<,>,between之类的

l          需要结果集group by /order by。另一方面,如果某个列的变动很频繁,则不宜在该列上建聚合索引。到底怎么定,还是要让事实说话,用show plan比较一下各种方案的差异总是有必要的

l          对于like '%xxx%'的查询,普通的索引起不了作用,可以使用FullText Search

### 使用游标索引高效查询数据 在数据库操作中,游标是一种用于遍历结果集的强大工具。当结合索引使用时,它可以显著提高查询效率,尤其是在处理大量数据的情况下。 #### IndexedDB 中的游标索引 IndexedDB 提供了一种灵活的方式来管理访问客户端存储的数据。通过定义对象存储及其关联的索引,可以快速检索特定范围内的记录[^3]。以下是基于 IndexedDB 的游标索引使用的示例: ```javascript function cursorGetDataByIndex(db, storeName, indexName, keyRange) { const transaction = db.transaction([storeName], 'readonly'); const objectStore = transaction.objectStore(storeName); const index = objectStore.index(indexName); const request = index.openCursor(keyRange); // 打开指定键范围的游标 request.onerror = function(event) { console.error('Error occurred while opening the cursor:', event.target.error); }; request.onsuccess = function(event) { let cursor = event.target.result; if (cursor) { console.log(`Key: ${cursor.key}, Value:`, cursor.value); cursor.continue(); // 移动到下一个匹配项 } else { console.log('All matching records have been processed.'); } }; } ``` 此代码片段展示了如何利用 `openCursor` 方法以及索引来高效地筛选并迭代符合条件的对象集合。 #### MySQL 中的游标与批量数据处理 对于服务器端数据库如 MySQL,在 MyBatis 集成场景下采用游标代替传统的 LIMIT 子句能够提升性能表现[^2]。下面是一个简单的 SQL 游标实现例子: ```sql DELIMITER $$ CREATE PROCEDURE FetchDataUsingCursor() BEGIN DECLARE done INT DEFAULT FALSE; DECLARE current_id BIGINT; -- 定义游标 DECLARE data_cursor CURSOR FOR SELECT id FROM your_table WHERE some_condition; -- 设置结束标志 DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; OPEN data_cursor; read_loop: LOOP FETCH data_cursor INTO current_id; IF done THEN LEAVE read_loop; END IF; -- 对当前行做进一步处理逻辑... INSERT INTO temp_results (processed_id) VALUES (current_id); END LOOP; CLOSE data_cursor; END$$ DELIMITER ; ``` 该脚本创建了一个名为 `FetchDataUsingCursor` 的存储过程,它会逐条读取满足条件的结果并通过循环逐一处理每一笔资料[^1]^。 #### MongoDB 中游标的数组转换应用案例 MongoDB 支持直接将游标转化为数组形式以便于后续计算或者展示用途[^4]。例如: ```javascript // 假设我们有一个已存在的游标实例 myCursor var documentArray = myCursor.toArray(); documentArray.forEach(function(doc){ printjson(doc._id + ": " + doc.someField); }); ``` 这里演示了怎样把来自 MongoDB 查询返回的一个动态游标转为静态 JavaScript 数组结构,并对其进行简单打印输出操作^。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值