繁体   English   中英

Django查询优化-何时使用sql和何时使用python

[英]django query optimization - when to use sql and when to use python

我正在寻找一种通用的经验法则,它决定何时重新查询数据库更快,何时使用python从缓存中提取数据更快。

假设我需要从数据库中同时提取两件事:所有披萨和一个pk = 5的特定披萨。

更优化的是:

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

要么

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

当然,它取决于数据库。 例如,如果披萨有1000万行,则很显然,重新查询sql更好,并且如果披萨有10行,即使对字段进行了索引,python也可能更快。

任何人都可以帮助中端产品进行进一步优化吗? 例如,披萨是几百行? 几千行?

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

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

  • 更短更清晰
  • ORM完全知道您想要什么,因此可以在该级别上进行任何进一步的优化,而不必将其推送到您的应用程序中
  • 它避免了在Web服务器中进行(可能)密集的计算

此外,还有一些值得深思的地方:如果您的表足够小,以至于python比数据库快,那么速度重要吗?

您可能需要阅读过早的优化

例如,如果披萨有1000万行,则很显然,重新查询sql会更好;如果披萨有10行,即使对字段进行了索引,python也会更快。

好吧...第一句话:是的。 第二句话:不确定,但也不重要。 因为只有很少的比萨饼时,nighter命令将花费大量时间。

任何人都可以帮助中端产品进行进一步优化吗?

我猜是不像您预期​​的那样,但是是的:由于我们同意在有很多披萨时使用.get()会更快,并且由于我们认为只有在有许多披萨时才需要关注性能,因此将来比萨的数量可能会增加,我认为我们可以同意使用.get()是正确的做法。

除了性能-它的可读性也更明显,因此您确实应该走这条路。

另外,请注意,您可以在QuerySet上使用方法( .all()返回QuerySet !)来过滤所需的内容。 这种工作方式是“幕后的魔法”-因此,假设找到了反对该假设的证据,就可以对其进行优化。 因此,您应该使用这些方法,直到达到真正需要目标优化的地步。 而且, 如果您达到了这一点,您可以进行基准测试并获得可靠的答案。

我感谢@ ch3ka和@goncalopp的回复,但我认为他们没有直接回答问题,因此,这是我对自己进行一些分析的照片:

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

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

pizzas = Pizza.objects.all()

我做了两个测试:

Test1:通过查看pk,在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是可能摘心的枚举。 我选择了枚举,因为我认为这是与索引数据库字段的正确比较

耗时0.3毫秒

使用Django调试工具栏,一个简单的索引sql查询所花费的时间约为0.3毫秒。

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

如果我计算错误或得出错误的结论,我将不胜感激。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM