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秒.
该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堆栈.