django 排除的性能问题

2024-02-01

我有一个 Django 1.8 应用程序,并且使用 MsSQL 数据库,以 pyodbc 作为数据库后端(使用“django-pyodbc-azure”模块)。

我有以下型号:

class Branch(models.Model):
    name = models.CharField(max_length=30)
    startTime = models.DateTimeField()

class Device(models.Model):
    uid = models.CharField(max_length=100, primary_key=True)
    type = models.CharField(max_length=20)
    firstSeen = models.DateTimeField()
    lastSeen = models.DateTimeField()

class Session(models.Model):
    device = models.ForeignKey(Device)
    branch = models.ForeignKey(Branch)
    start = models.DateTimeField()
    end = models.DateTimeField(null=True, blank=True)

我需要查询会话模型,并且我想排除一些具有特定设备值的记录。所以我发出以下查询:

sessionCount = Session.objects.filter(branch=branch)
                          .exclude(device__in=badDevices)                                             
                          .filter(end__gte=F('start')+timedelta(minutes=30)).count()

badDevices 是一个预先填充的设备 ID 列表,包含大约 60 个项目。

badDevices = ['id-1', 'id-2', ...]

此查询大约需要 1.5 秒才能完成。如果我从查询中删除排除项,则需要大约 250 毫秒。

我打印了为此查询集生成的 sql,并在我的数据库客户端中进行了尝试。两个版本的执行时间都在大约 250 毫秒内。

这是生成的 SQL:

SELECT [session].[id], [session].[device_id], [session].[branch_id], [session].[start], [session].[end] 
FROM [session] 
WHERE ([session].[branch_id] = my-branch-id AND 
NOT ([session].[device_id] IN ('id-1', 'id-2', 'id-3',...)) AND 
DATEPART(dw, [session].[start]) = 1 
AND [session].[end] IS NOT NULL AND 
[session].[end] >= ((DATEADD(second, 600, CAST([session].[start] AS datetime)))))

因此,在数据库级别使用排除似乎不会影响查询性能,但在 django 中,如果我添加排除部分,查询运行速度会慢 6 倍。可能是什么原因造成的?


一般问题似乎是 django 正在做一些额外的工作来准备exclude条款。在该步骤之后,当 SQL 生成并发送到数据库时,django 端没有发生任何可能导致如此严重延迟的有趣事情。

就您而言,可能导致这种情况的一件事是某种预处理badDevices。举例来说,如果badDevices is a QuerySet那么 django 可能正在执行badDevicesquery 只是为了准备实际查询的 SQL。在以下情况下可能会发生类似的情况device有一个非默认主键。

当然,另一件事可能会延迟 SQL 准备django-pyodbc-azure。也许它在编译查询时做了一些奇怪的事情,并且成为了瓶颈。

不过,这都是疯狂的猜测,所以如果您仍然遇到这个问题,请发布Device and Branch模型以及确切的内容badDevices以及从查询生成的 SQL。那么也许某些场景至少可以被消除。

编辑:我想这一定是Device.uid场地。 django 或 pyodbc 可能会被非默认主键混淆,并在生成查询时获取所有设备。尝试两件事:

  • Replace device__in with device_id__in, device__pk__in and device__uid__in并再次检查每一项。也许更明确的查询将更容易让 django 转换为 SQL。您甚至可以尝试更换branch with branch_id, 万一。

  • 如果上述方法不起作用,请尝试将排除表达式替换为原始 SQL where 子句:

    # add quotes (because of the hyphens) & join
    badDevicesIdString = ", ".join(["'%s'" % id for id in badDevices])
    
    # Replaces .exclude()
    ... .extra(where=['device_id NOT IN (%s)' % badDevicesIdString])
    

如果两者都不起作用,那么问题很可能出在整个查询上,而不仅仅是exclude。在这种情况下还有更多选择,但请先尝试上述方法,如有必要,我稍后会更新我的答案。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

django 排除的性能问题 的相关文章

随机推荐

  • Selenium WebDriver 等待元素显示

    我在 Google 和 SO 网站上进行了搜索 得到了 JAVA 的答案 但似乎没有得到 node js 的答案 我有一个网络应用程序需要一些时间才能加载 我希望 selenium 程序等待页面加载 然后执行一些操作 我当前的代码如下 de
  • 当标记位于打开的信息框后面时 - 使用 InfoBox 插件 Google Maps API v3 处理鼠标悬停事件

    我在使用 Google Maps API v3 和使用 InfoBox 插件时遇到了问题 特别是针对此可用性问题用例 由于我的地图需要将鼠标悬停在每个相应标记上时打开自定义信息框 因此当地图上有 2 个非常接近的标记时 即使其中一个标记位于
  • 适用于 iOS 开发人员和 Mac 开发人员的 Apple 证书已过期“证书的颁发者无效”[重复]

    这个问题在这里已经有答案了 该证书的颁发者无效 适用于 IOS 和 Mac 的 Apple 证书不起作用 全部显示它们已过期 但实际上并未过期 首先 您需要清洁钥匙链 从所有地方删除 Apple 全球开发者关系认证机构 从System an
  • 使用电话号码的 Firebase 身份验证返回内部错误

    我将我的应用程序设置为能够使用 firebase 发送 Apple 通知 并验证它是否可以使用控制台运行 现在我想做建立在 APN 之上的电话身份验证 所以我写了这个 PhoneAuthProvider provider verifyPho
  • 如何编写 FQL 来获取新闻源

    我必须获取新闻源 公共墙上 上的所有数据 我应该写什么查询 我写 SELECT likes message FROM stream WHERE source id lld limit 50 查询 但它正在返回我的墙值 我想获取我的墙上以及公
  • 从分组查询中删除连接操作

    我有一张桌子 看起来像 usr id query ts 12345 2019 05 13 02 06 123444 2019 05 15 04 06 123444 2019 05 16 05 06 12345 2019 05 16 02 0
  • 如何扩展行并填写给定开始和结束之间的数字

    我有这个数据框 df lt tibble x c 1 10 x
  • 克隆git仓库失败

    当我尝试从存储库克隆以下内容时 git clone git gitorious org qt qt5 git qt5 我收到此错误 fatal Unable to look up gitorious org port 9418 This i
  • Django 找不到静态文件。需要第二双眼睛,我快疯了

    Django 不会为我的静态文件提供服务 这是error回到 13 Jun 2014 06 12 09 GET refund HTTP 1 1 200 2927 13 Jun 2014 06 12 09 GET static css boo
  • SeleniumBasic VBA 使用 WebElement 方法最快的 WebElement 循环

    我注意到完成操作需要相当长的时间 我正在使用最新的 SeleniumBasic for VBA 使用 ChromeDriver 从表中提取数据 https github com florentbr SeleniumBasic https g
  • 渐变作为按钮边框颜色?

    我想为 Xamarin Forms 按钮设置渐变边框颜色 我怎样才能做到这一点 Current Desire 有一些选项通过 Google 上升到了顶峰 但似乎没有一个选项是独立于平台且适用于 Button 的 举几个例子 使用WebVie
  • 在页面内的 div 中显示控制台错误和警报

    我正在为我的网络应用程序构建一个调试工具 我需要在 div 中显示控制台错误 我知道我可以使用自己制作的类似控制台的对象并使用它 但为了将来的使用 我需要将所有控制台错误发送到 window 实际上我想捕获控制台事件 要保持控制台正常工作
  • create-react-app React Js 的漏洞

    每次我创建一个反应应用程序时npx create react app
  • jquery 选择删除选项

    我目前正在成功使用它来删除选项 select select gender option value initial remove 有没有办法删除选项而不添加到选择器 如下所示 select select gender val initial
  • 过滤涉及安全约束的请求

    我有一个 Java Web 应用程序 它使用安全约束来锁定对资源的访问 当 Ajax 请求需要身份验证时 我尝试操纵 HTTP 401 响应 因此我创建了一个过滤器来观察响应中的 HTTP 状态并根据需要进行相应修改 问题是 似乎如果需要身
  • 使用lambda表达式连接pyqt中的槽

    我正在尝试将插槽与 lambda 函数连接起来 但它没有按我预期的方式工作 在下面的代码中 我成功正确连接了前两个按钮 对于我循环连接的后两个 这是错误的 之前有人问过同样的问题 Qt 使用 lambda 将槽与参数连接 https sta
  • OrderedDict 不按顺序排列

    这个循环的想法是迭代列表 如果对象的某个属性不是 OrderedDict 的键 则会添加它 它是对象列表的字典 for object in someList if object DATE not in myOrderedDict myOrd
  • 使 Omni 能够在 Windows 上的 vim 7.2 上运行

    我正在尝试将 Omni Complete 功能与 gVim 7 2 一起使用 但在 Windows 上我不断收到一条错误消息 错误 需要使用 python 编译 vimE117 未知功能 pythoncomplete complete 看起
  • 如何确定变量的内存占用(大小)?

    PHP 或 PHP 扩展 中是否有函数可以找出给定变量使用了多少内存 sizeof只是告诉我元素 属性的数量 memory get usage有帮助的是它给了我所使用的内存大小whole脚本 有没有办法对单个变量执行此操作 请注意 这是在开
  • django 排除的性能问题

    我有一个 Django 1 8 应用程序 并且使用 MsSQL 数据库 以 pyodbc 作为数据库后端 使用 django pyodbc azure 模块 我有以下型号 class Branch models Model name mod