django查询优化 - 何时使用sql以及何时使用python

时间:2014-10-29 15:32:15

标签: python sql django query-optimization

我正在寻找一个通用的经验法则,它可以更快地重新查询数据库,以及何时使用python并从缓存中提取数据的速度更快。

我们假设我需要从数据库中提取两个同时的东西:所有比萨饼和pk = 5的特定披萨。

更优化的内容:

pizzas = Pizza.objects.all()   
specific_pizza = Piazza.objects.get(pk=5)

OR

pizzas = Pizza.objects.all()
for pizza in pizzas:
    if pizza.pk == 5
        specific_pizza = pizza
        break 

当然这取决于数据库。例如,如果比萨是1000万行,显然重新查询sql更好,如果比萨是10行,即使字段被索引,python可能更快。

任何人都可以帮助中间范围内更优化吗?例如,比萨饼是几百行?成千上万行?

3 个答案:

答案 0 :(得分:2)

这个问题没有明确的答案 - 正如你所说,这取决于数据库(可能还有它的位置,表格的数量和大小......)。你必须在你的特定环境中进行测试。

除了原始速度之外,使用第一个版本还有一些重要优势:

  • 它更短更清晰
  • ORM确切地知道你想要什么,所以任何进一步的优化都可以在那个级别完成,而不是将它们推送到你的应用程序
  • 它避免在您的网络服务器中进行(可能)密集的计算

另外,还有一些值得深思的问题:如果你的桌子足够小以至于python比DB快,那么速度是否重要?

您可能希望阅读过早优化

答案 1 :(得分:1)

  例如,如果比萨饼是1000万行,那很明显   重新查询sql更好,如果比萨饼是10行,即使是   字段被索引,python可能更快。

嗯......第一个声明:是的。第二个声明:不确定,但也不重要。 因为当只有很少的比萨饼时,更明智的命令将需要一段时间。

  

任何人都可以帮助中间范围内更优化吗?

不是你想象的那样,我想,但是是的:因为我们同意在有很多比萨饼的时候使用.get()会更快,而且因为我们发现当有很多比萨饼时,性能只是一个问题,考虑到事实上,未来比萨饼的数量可能会增长,我想我们可以同意使用.get()是正确的做法。

除了性能之外 - 它显然更具可读性,所以你真的应该走那条路。

另请注意,您可以使用QuerySet上的方法(.all()返回QuerySet!)来过滤您想要的内容。这是如何工作的“幕后魔术” - 因此假设被优化,直到找到针对该假设的证据。所以你应该使用这些方法,直到你真正需要目标优化。 如果你曾经达到过这一点,你可以通过基准测试并获得可靠的答案。

答案 2 :(得分:0)

我很欣赏@ ch3ka和@goncalopp的回复,但我不认为他们直接回答了这个问题,所以这是我自己拍摄的一些资料:

最重要的是,我发现python查找甚至与sql相同,大约有1000个条目:

假设我已经查询了数据库并收到了1000个比萨饼:

pizzas = Pizza.objects.all()

我做了两次测试:

测试1: 通过查看pk's,找到1000个披萨中的特定披萨:

for pizza in pizzas:
    if pizza.pk == 500
        specific_pizza = pizza
        break 

花费0.2毫秒

的Test2: 根据披萨成员过滤,并创建一个新列表:

mushroom_pizzas=[pizza for pizza in pizzas if pizza.topping==Pizza.MUSHROOM]

其中MUSHROOM是可能的打顶的枚举。我选择了enum,因为我认为这是与索引的DB字段的正确比较

花了0.3毫秒

使用Django调试工具栏,简单的索引SQL查询所需的时间大约为0.3毫秒。

我确实认为像@goncalopp和@ ch3ka一样,因为简单的索引查询已经是0.3毫秒,所以没有必要去python进行优化。因此,即使我事先知道条目的数量将少于1000,甚至远低于1000,我仍然总是使用sql。

如果我算错了或得出了错误的结论,我会很感激。