了解MySQL游标类型

Mic*_*ina 15 python mysql sql

MySQL版本:5.5.37-0ubuntu0.14.04.1

我目前正在编写一个python脚本,它利用大量的MySQL表和查询来获取存储在表中的倒排索引的结果.

我注意到,在执行查询时选择合适的类型光标的MySQLdb的Python模块中有一个真正对性能影响较大,想知道是否有人能解释或提供了可靠的资源解释其光标时使用.

例如,使用SSCursor执行此查询40次需要7秒:

SELECT Pages.PageID,
       Pages.PageName,
       Counter AS TermFreq,
       Pages.Length,
       (Counter / LOG(Length)) AS Weight
FROM Pages
INNER JOIN TermOccurrences ON TermOccurrences.PageID = Pages.PageID
INNER JOIN Terms ON TermOccurrences.TermID = Terms.TermID
WHERE TermName = %s
ORDER BY Weight DESC
LIMIT 20;
Run Code Online (Sandbox Code Playgroud)

使用默认Cursor运行相同的查询40次需要0.004秒.

删除权重计算(计数器/ LOG(长度))使得此查询使用SSCursor再次快速执行.

我正在使用SSCursor,因为它证明在许多其他查询上具有非常优越的性能,然后突然变得非常慢.当它执行得如此之快时,更改回默认的Cursor让我感到惊讶.

编辑:更多的例子.

使用默认光标运行以下40次需要~3秒:

SELECT COUNT(*)
FROM Pages
INNER JOIN TermOccurrences ON TermOccurrences.PageID = Pages.PageID
INNER JOIN Terms ON TermOccurrences.TermID = Terms.TermID
WHERE TermName = %s AND Counter > 2
Run Code Online (Sandbox Code Playgroud)

使用SSCursor运行它大约需要0.002秒.

fif*_*nce 9

MySQLdb的文档提的是,标准的游标类使用mysql_store_result()而SSCursor使用mysql_use_result()"后者则必须确保能够执行另一个查询之前的所有行已经读".

所以,它是关于mysql_store_result()VS mysql_use_result().

MySQL的文档提到,mysql_use_result()启动一个结果集检索,而不实际读取结果集到客户端,喜欢了mysql_store_result()一样.因此,必须通过调用单独检索每一行mysql_fetch_row(),当然,在处理大型表时,这些行可能相当大.

同样在MySQLdb文档中:

SSCursor:"服务器端"游标.像Cursor一样但使用CursorUseResultMixIn.仅在处理可能较大的结果集时使用.

因此,SSCursor如果您的结果集太大而无法一次性进入您的客户端,那么主要是好的.

另见这些问题:

请注意,LIMIT 20查询永远不会那么大.您可能需要检查您的KEY.为了更好地了解为什么可能需要7秒,最好也可以在问题中包含db模式,这可能更适合DBA堆栈.