SSCursor in MySQL
2016-01-19 14-55-49 by KamushinThere are four kinds of cursors available in MySQL client side programming. In this article, I am going to
introduce the difference between Cursor
the normal one and SSCursor
the server side one and how to use SSCursor
.
First, let's see the definitions of those four cursors in MySQLdb
source code.
class Cursor(CursorStoreResultMixIn, CursorTupleRowsMixIn,
BaseCursor):
"""This is the standard Cursor class that returns rows as tuples
and stores the result set in the client."""
class DictCursor(CursorStoreResultMixIn, CursorDictRowsMixIn,
BaseCursor):
"""This is a Cursor class that returns rows as dictionaries and
stores the result set in the client."""
class SSCursor(CursorUseResultMixIn, CursorTupleRowsMixIn,
BaseCursor):
"""This is a Cursor class that returns rows as tuples and stores
the result set in the server."""
class SSDictCursor(CursorUseResultMixIn, CursorDictRowsMixIn,
BaseCursor):
"""This is a Cursor class that returns rows as dictionaries and
stores the result set in the server."""
In fact, there are two orthogonal features of cursors in MySQLdb. CursorDictRowsMixIn/CursorTupleRowsMixIn
controls result type and
CursorStoreResultMixIn/CursorUseResultMixIn
which we will focus on in this article controls the result will be store in server or client.
With the definitions, we know that SSCursor
stores result in the server rather than in the client.
server side VS client side
Two simple flows show how they works.
- client side
# mysql_store_result
while(True):
result = produce_part_result() # find part of results that can be filled into a network package
fill_network_package(result)
send_network_package
- server side
# mysql_use_result
while(True):
result = produce_part_result() # find part of results that can be filled into a network package
wait_until_the_client_invoke_`mysql_fetch_row()`
fill_network_package(result)
send_network_package
In fact, the MySQL server will not store results in server even if a SSCursor
is used, it will produce the part of results before fill them into
the network packages. So don't worry the memory use of the server when use SSCursor
.
how to use SSCursor
cur = conn.cursor(MySQLdb.cursors.SSCursor)
Here is a trap that commit
should be invoked after all of the results have been sent to client. Otherwise,
2014, "Commands out of sync; you can't run this command now"
error will be raised.
If you get Commands out of sync; you can't run this command now in your client code, you are calling client functions in the wrong order. This can happen, for example, if you are using mysql_use_result() and try to execute a new query before you have called mysql_free_result(). It can also happen if you try to execute two queries that return data without calling mysql_use_result() or mysql_store_result() in between.
commit
is also a query, or we can say request, so the program should read all of the results then invoke commit
.
advantages and disadvantages of using SSCursor
- Less memory use in the client.
- Get the first row more quickly.
- The whole results sending will be slower.