【问题标题】:I'm confused about MySQLdb server side cursor and client cursor我对 MySQLdb 服务器端游标和客户端游标感到困惑
【发布时间】:2016-02-15 17:13:39
【问题描述】:

我正在使用 python-mysql(MySQLdb) 来查询 Mysql 服务器。 游标模块有两种:一种是客户端游标,如:

cursor = db.cursor(MySQLdb.cursors.DictCursor)

另一种是服务器端游标,如:

cursor = db.cursor(MySQLdb.cursors.SSDictCursor)

文档说服务器端游标意味着Mysql会将一些结果缓存在mysql服务器端,然后将它们发送到客户端。我对此感到很困惑,比方说,如果我想杀死一个 mysql 服务器,我可以只使用多个服务器端游标,然后 mysql 将因为内存耗尽而死。此外,服务器大小光标是否有意义?默认情况下,Mysql 机制是当 mysql 检索到一条记录时,它会立即将其发送给客户端。缓存结果然后发送出去有意义吗?

我真的不知道我应该使用哪个游标,客户端游标还是服务器端游标?

【问题讨论】:

  • 不是一个答案,因为我将其基于另一个执行相同操作的 DBMS.... 在某些情况下,您会逐页显示结果,即使有(比如说)10 页,因为根据它们的排序方式,用户通常只查看前 1 个。那么,为什么要通过网络发送所有 10 个页面。
  • 问题是如果你需要 1 个页面,为什么要查询 10 个页面。那是糟糕的设计。

标签: mysql cursor mysql-python


【解决方案1】:

游标由三部分组成:

  • 一个查询
  • 查询结果
  • 指向检索数据的位置的指针。

根据查询,结果可以被缓存,也可以由引擎部分检索:

例如通常不缓存的查询结果:

SELECT * FROM sometable;

每次您请求一行时,MySQL(和大多数其他 DBMS)只会从表中检索一行。但是,如果您在读取提交样式中使用 InnoDB 和 ACID 兼容事务,它可以使用表锁。

第二种情况是一个查询,结果必须被缓存:

SELECT * FROM sometable ORDER BY a,b,c;

在这种情况下,MySQL(以及大多数其他 DBMS)必须首先以正确的顺序获取所有数据。为此,将在磁盘上的#tmp 位置创建一个临时表。这可能会导致磁盘已满(大多数情况下翻译为out of memory 错误)问题和连接丢失。然而,MySQL 继续运行。

【讨论】:

    【解决方案2】:

    我不是最伟大的数据库忍者,但通常情况下,服务器软件中内置的东西在一般或常见情况下并不真正有用,但在那个小角落情况下真的非常棒。

    Nimdil 给了你一个,但这是另一个:

    http://techualization.blogspot.com/2011/12/retrieving-million-of-rows-from-mysql.html

    这个人断言 SScursor 更像是一个“无缓冲”游标。

    这种说法似乎是矛盾的:

    http://dev.mysql.com/doc/refman/5.7/en/cursor-restrictions.html

    无论如何,服务器端游标的使用似乎是在您处理数据集时,这样您的查询可能会压倒客户端。

    【讨论】:

    • 您说链接#2 似乎与链接#1 相矛盾,但他们在谈论不同的事情。 #1 正在谈论 Python 库中的“服务器端光标”SSCursor,这确实是错误的名称。当它从服务器获取行时,它只是调用 mysql_use_result() 而不是 mysql_store_result()。您可以在此处阅读有关这些内容的更多信息:dev.mysql.com/doc/refman/5.7/en/mysql-use-result.html #2 正在谈论不同的服务器端结果集功能,该功能在服务器本身中实现。
    【解决方案3】:

    我相信 MySQL 宁愿杀死你的游标也不会因为几个过大的游标而崩溃。

    当服务器端光标有意义时,您可以考虑几种情况。例如,如果您的网络连接速度较慢且光标很大,您可以处理一小部分数据,您可以获得更快的数据,可能会将其传递给其他系统,然后再获取更多数据。这样整体求解速度会更快。

    我能想到的其他情况是,当您在客户端下拥有非常强大的数据库服务器和相当糟糕的机器时 - 这样,在大数据集的情况下,数据库更容易为您的客户端保存整个集合,而客户端可以有效地微观管理内存。

    可能还有许多其他情况。如果您认为它没有意义,请不要使用它。并非所有选项都适用于每种设置。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-08
      • 1970-01-01
      • 2015-03-24
      • 1970-01-01
      • 2015-07-12
      • 1970-01-01
      • 1970-01-01
      • 2012-03-22
      相关资源
      最近更新 更多