• MySQl的游标特性简介


      MySQL在服务器端提供只读的、单向的游标,而且只能在存储过程或者更底层的客户端API中使用。因为MySQL游标中指向的对象都是存储在临时表中而不是实际查询到的数据,所以MySQL游标总是只读的。它可以逐行指向查询结果,然后让程序做进一步的处理。在一个存储过程中,可以有多个游标,也可以在循环中“嵌套”地使用游标。

      MySQL的游标设计也为粗心的人“准备”了陷阱。因为是使用临时表实现的,所以它在效率上给开发人员一个错觉。需要记住的最重要的一点是:当你打开一个游标的时候需要执行整个査询。考虑下面的存储过程:

    1  CREATE PROCEDURE bad_cursor()
    2  BEGIN
    3     DECLARE film_id INT;
    4     DECLARE f CURSOR FOR SELECT film_id FROM sakila.film;
    5     OPEN f;
    6     FETCH f INTO film_id;
    7     CLOSE f;
    8  END

      从这个例子中可以看到,不用处理完所有的数据就可以立刻关闭游标。使用Oracle或 者SQL Server的用户不会认为这个存储过程有什么问题,但是在MySQL中,这会带来很多的不必要的额外操作。使用SHOW STATUS来诊断这个存储过程,可以看到它需要做1000个索引页的读取,做1000个写入。这是因为在表sakila.film中有1000条记录,而所有这些读和写都发生在第五行的打开游标动作。

      这个案例告诉我们,如果在关闭游标的时候你只是扫描一个大结果集的一小部分,那么存储过程可能不仅没有减少开销,相反带来了大量的额外开销。这时,你需要考虑使用LIMIT来限制返回的结果集。

      游标也会让MySQL执行一些额外的I/O操作,而这些操作的效率可能非常低。因为临时内存表不支持BLOB和TEXT类型,如果游标返回的结果包含这样的列的话,MySQL就必须创建临时磁盘表来存放,这样性能可能会很糟。即使没有这样的列,当临时表大于tmp_table_size的时候,MySQL也还是会在磁盘上创建临时表。

      MySQL不支持客户端的游标,不过客户端API可以通过缓存全部查询结果的方式模拟客户端的游标。这和直接将结果放在一个内存数组中来维护并没有什么不同。

    作者:小家电维修

    相见有时,后会无期。

  • 相关阅读:
    POJ1942-Paths on a Grid
    CodeForces 245C-Game with Coins
    codeforces 244B-Undoubtedly Lucky Numbers 搜索
    URAL
    HDU-1134 卡特兰数+java大数模板
    素数线性筛
    KMP讲解
    bzoj 3143: [Hnoi2013]游走
    bzoj 3238: [Ahoi2013]差异
    bzoj 2208: [Jsoi2010]连通数
  • 原文地址:https://www.cnblogs.com/lizexiong/p/15549176.html
Copyright © 2020-2023  润新知