这是基于我面临的面试问题。
非常短的定义可以是
它可用于操作行
由查询返回。
除了使用光标之外(列出了点here http://msdn.microsoft.com/en-us/library/ms191179.aspx在MSDN上),我心中有一个问题,如果我们可以使用查询或存储过程执行所有操作(如果我没有错的话,就像我们可以使用Transact-SQL for ms-sql),有什么具体的点我们应该使用光标吗?
与大型结果集相比,使用光标就像使用视频流而不是一次性下载视频,然后在下载后观看它。
如果你下载,你必须有几GB的空间和耐心等待下载完成。现在,无论您的机器或网络有多快,每个人都以相同的速度观看电影。
通常,任何查询都会发送到服务器并执行,然后通过网络将结果集发送给您,这是一次突发的活动。
游标将使您可以逐行访问数据,并且仅在您请求时(实际上可以查看它)流式传输每一行。
- 光标可以节省您的时间 - 因为您无需等待完整记录集的处理和下载
- 它将节省服务器和客户端上的内存,因为它们不必将大量内存专用于结果集
- 平衡您的网络和服务器的负载 - 在“突发”模式下工作通常效率更高,但它可能会完全阻塞您的服务器和网络。对于多用户环境来说,这样的延迟是很少需要的。流式传输为其他操作留下了空间。
- 允许对查询表(在某些条件下)进行不直接影响游标的操作。因此,当您将光标放在一行上时,其他进程可以读取、更新甚至删除其他行。这对于非常繁忙的表、许多并发读取和写入尤其有帮助。
然而,这给我们带来了一些警告:
一致性:使用游标,您(通常)不会对数据的一致快照进行操作,而是对一行进行操作。因此,您的并发性/一致性/隔离性保证从整个数据库(ACID)下降到只有一行。您通常可以告知 DBMS 您想要什么级别的并发性,但如果您太挑剔(锁定您所在的整个表),您将浪费服务器端节省的许多资源。
单独传输每一行可能效率非常低,因为每个数据包都有协商开销,您可以通过为每个数据包发送大的(可能是压缩的)数据块来避免协商开销。 (没有数据库服务器或客户端库愚蠢到单独传输每一行,两端都有缓存和分块,但它仍然是相关的。)
游标更难正确使用。考虑一个具有大结果集的查询,促使您使用游标,该游标使用带有聚合函数的 GROUP BY 子句。 (此类查询在数据仓库中很常见)。 GROUP BY 可以完全破坏您的服务器,因为它必须立即生成并存储整个结果集,甚至可能持有其他表的锁。
经验法则:
- 如果您处理快速创建的小型结果集,请不要使用游标。
- 游标擅长于即席、复杂(参考)、具有大结果集和低一致性要求的顺序查询。
“顺序性质”意味着查询中的大量 GROUP BY 子句中没有聚合函数。服务器可以懒洋洋地决定计算 10 行供游标从缓存中使用,并同时执行其他操作。
HTH
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)