数据库同步工具
sqlserver,Mysql数据同步软件

在您的数据库中不向randos说

在线QQ客服:1922638

专业的SQL Server、MySQL数据库同步软件

当我使用我的第一个ORM时,我想知道”为什么它们没有包含方法?”似乎很容易添加。尽管出于多种原因可能要随机从数据库中提取一条记录,但是除非您只随机分配有限数量的记录,否则不应该使用SQL函数。在本文中,我们将研究这种简单的SQL运算符如何导致很多性能问题,以及一些可用于修复它的不同技术。

您可能知道,我运行CodeTriage,这是开始帮助开源的最佳方法,并且我写过关于改善该站点上数据库性能的文章:

  • 使用Rack Mini Profiler查找慢查询
  • 使用Heroku昂贵的查询仪表板查找慢查询
  • 如何将数据库服务器负载减少80%

最近,我正在运行该命令,以查看其中的一些优化后的样子,而令我惊讶的是,我花了32%的数据库时间用于两个带有a的查询。/p>

 

让我们看一下第一个查询,以了解它为什么变慢。

 

该查询每周使用一次,以鼓励用户在有帐户但未订阅帮助的情况下在开放源代码回购中注册” triage”问题。我们会发送一封包含3个回购建议的电子邮件,其中包括一个随机回购。毕竟,这似乎是一种很好的用法,我们确实希望获得随机结果。为什么这样不好?

虽然我们告诉Postgres只给我们一条记录,但并不仅如此。它在返回记录之前对 all 条记录进行排序。

虽然您可能会认为它确实在做类似的事情。当我编写此代码时,它的运行速度非常快,因为我在数据库中只有几个存储库。但是现在有2,761个存储库正在增长。并且每次执行此查询时,数据库都必须为每个存储库加载行,并花费CPU能力来对其进行随机排序。

您可以看到另一个与用户表做相同事情的查询:

 

此相对较小的查询的每次执行大约需要13毫秒。

所以,如果不好,我们该如何解决?这是一个非常困难的问题。在很大程度上取决于您的应用程序以及您如何访问数据。

对于我来说,我通过生成随机ID然后提取该记录来解决此问题。在这种情况下,我知道ID是相对连续的,所以我拉出最高的ID,从1到1之间选择一个随机数,然后执行查询,以获取该ID的记录。

速度更快吗?哦耶。以下是与之前相同的查询,但替换为:

 

我们将查询执行时间从13ms缩短到了1ms以下。

这里有一些需要注意的严重警告。我的实现会缓存max id,这对于我的用例来说是很好的,但可能不适用于您的用例。可以使用类似以下的命令完全在SQL中完成此操作:

 

一如既往,在优化前后对SQL查询进行基准测试。此实现不能很好地处理稀疏填充的ID值,也不能考虑根据条件随机选择一个大于可用的最大ID。本质上,如果要做到“正确”,则需要将与主查询相同的条件应用于子查询。

对于我的情况,如果遇到一些失败就很好,而且我知道我只适用最基本的条件。您的需求可能没有那么灵活。

如果您想知道是否没有内置的方法可以做到这一点?,事实证明,它是Postgres 9.5中引入的。感谢@HotFusionMan向我介绍了它。

这是我发现的关于使用的最佳博客。缺点是它不是“真正随机的”(如果这对您的应用程序很重要),并且您不能使用它仅检索1个结果。我可以通过查询唯一的表采样1%来破解它。然后,我使用那1%来获取ID,然后将其限制为第一条记录。像这样:

 

虽然这是有效的,而且比返回很多数据(成千上万的行)的查询要快得多,但对于数据很少的查询来说却很慢。

当我优化https://www.codetriage.com时,我发现了另一个使用的查询。它用于查找特定回购的开源问题。由于问题的存储方式,这些ID并不是非常连续的,因此我以前的技巧(采样到==随机ID)也不会起作用。我需要一种更健壮的方法来随机化数据,并且我认为可能会更好。

尽管某些存储库有数千个问题,但50%的问题有27个或更少的问题。当我使用该技术进行此查询时,它使我的小查询确实变慢了,而以前的慢查询也变快了。由于我的查询数字偏向较小的一侧,因此并不是净收益,因此我坚持使用原始方法。

您是否已替换为另一种更有效的技术?让我通过Twitter @schneems知道它。

未经允许不得转载:数据库同步软件|Mysql数据同步软件|sqlserver数据库同步工具|异构同步 » 在您的数据库中不向randos说

分享到:更多 ()

syncnavigator 8.6.2 企业版

联系我们联系我们