MySQL版本:5.5.37-0ubuntu0.14.04.1
我目前正在编写一个python脚本,它利用大量的MySQL表和查询来获取存储在表中的倒排索引的结果。
我注意到在执行查询时在MySQLdb python模块中选择正确类型的Cursor会对性能产生很大的影响,并且想知道是否有人可以解释或提供可靠的资源来解释哪些光标在何时使用。
例如,使用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;
使用默认Cursor运行相同的查询40次需要0.004秒。
删除权重计算(Counter / LOG(Length))可以使用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
使用SSCursor运行它大约需要0.002秒。
答案 0 :(得分:9)
MySQLdb docs提到标准Cursor类正在使用mysql_store_result()
而SSCursor正在使用mysql_use_result()
“,后者必须确保在执行另一个查询之前已读取所有行”
所以它是关于mysql_store_result()
vs mysql_use_result()
。
MySQL docs提到mysql_use_result()
启动结果集检索而不实际将结果集读入客户端,如mysql_store_result()。因此,必须通过调用mysql_fetch_row()
单独检索每一行,当然,在处理大型表时,这些行会相当大。
同样在MySQLdb文档中:
SSCursor:“服务器端”游标。像Cursor一样使用 CursorUseResultMixIn。仅在潜在处理时使用 大结果集。
如果您的结果集太大而无法一次性进入您的客户端,那么SSCursor
主要是好的。
另见这些问题:
请注意,LIMIT 20
查询永远不会那么大。您可能需要检查您的KEY。为了更好地了解为什么可能需要7秒,最好也可以在问题中包含数据库模式,这可能更适合DBA stack。