【问题标题】:Python list vs. MySQL Select performancePython list vs. MySQL Select 性能
【发布时间】:2009-09-04 18:47:16
【问题描述】:

我在 MySQL 表中有一个包含 15k 条目的大列表,我需要从中选择一些项目,很多次。例如,我可能想要数字字段介于 1 和 10 之间的所有条目。

在 SQL 中这很容易:

SELECT text FROM table WHERE number>=1 AND number<10; 

如果我将整个表提取到 Python 列表中:

PyList = [[text1, number1], [text2, number2], ...]

然后我可以通过遍历整个列表来提取我想要的相同文本值

for item in PyList
    if item[1] >=1 and item[1]<10:
        result.append(item[0])

现在,两者之间的性能问题是我必须为滑动窗口执行此操作。我想得到介于 1 和 10 之间的那些,然后是 2 和 11、3 和 12、... 14990 和 15000 对于这么大的列表,哪种方法更快?

我正在考虑的 Python 改进是按数字对 Python 列表进行预排序。当窗口移动时,我可以从result 中删除最小值并附加所有验证下一个条件的元素以获得新的result。我还将跟踪 PyList 中的索引,以便知道下一次迭代从哪里开始。这样可以避免我再次遍历整个列表。

我不知道如何为非常相似的连续选择加速 MySQL,我不知道它如何在内部工作以了解两种方法之间的性能差异。

您将如何实现这一点?

【问题讨论】:

    标签: python mysql


    【解决方案1】:

    只需在您的数据库中为number 定义一个索引,然后数据库就可以立即生成结果集。另外,如果这是您的下一步,它也可以对这些集合进行一些计算。

    数据库实际上非常适合此类查询,我会先让它完成它的工作,然后再尝试其他东西。

    【讨论】:

    • 谢谢,我不知道 MySQL 中的索引,所以我从您的帖子中了解到这一点。
    【解决方案2】:

    将数据拉入内存肯定比运行约 15,000 次查询要快得多。

    我的建议是确保 SQL 查询按number 对数据进行排序。如果数据已排序,则可以使用bisect标准库模块中非常快速的查找方法来查找索引。

    【讨论】:

      【解决方案3】:

      将所有数据读入 Python(从您提到的数字中,它应该很容易放入内存中),如您所说的进入变量 pylist,然后准备一个辅助数据结构,如下所示:

      import collections
      d = collections.defaultdict(list)
      for text, number in pylist:
        d[number].append(text)
      

      现在,要获取包含low 和排除high 之间数字的所有文本,

      def slidingwindow(d, low, high):
          result = []
          for x in xrange(low, high):
              result.extend(d.get(x, ()))
          return result
      

      【讨论】:

        【解决方案4】:

        如果没有实际性能很难回答,但我的直觉是使用绑定变量的 SQL 会更好(我不是 MySQL 专家,但在这种情况下查询语法 should be 类似于 %varname )。

        原因是您只会在需要时返回数据(因此用户界面会提前做出响应),并且您将依赖针对此类操作高度优化的系统。另一方面,检索较大的数据块通常比检索较小的数据块更快,因此“完整的 python”方法可能有其优势。

        但是,除非您遇到严重的性能问题,否则我仍然会坚持使用 SQL,因为它会导致代码更简单、易于阅读和理解。

        【讨论】:

          猜你喜欢
          • 2013-10-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-02-14
          • 1970-01-01
          • 2011-08-23
          • 2014-07-12
          • 1970-01-01
          相关资源
          最近更新 更多