数据库优化系列:本文是一个系列的一部分,可帮助开发人员优化其数据库查询。如果您还遇到缓慢查询,欢迎您与我联系。
Tom Witowsky(@Devumbibeer)在Twitter上共享一个缩放问题,即他的服务Opendor.me,它可以帮助任何开发人员共享并突出显示它们的开源工作.As服务会长,越来越多的数据存储在数据库中,需要浏览。 。一个特别慢的查询,他需要帮助优化是获取已经是服务的一部分的随机用户,组织和存储库。
在我们查看如何优化查询的情况下,我们需要了解数据库进程如何处理此类查询。在优化您要求他们执行的大多数查询时,它们都会出现优秀,但它们有它们的极限。但是,选择某些随机行是一个SQL AntiPattern作为数据库没有对此用例具有优化。
这是数据库的一项琐碎的任务,如果您只有一些记录,但您拥有的记录越多,此方法的效率就越少,仍然可以使用稍大的表格有效地完成所有记录到内存中,但排序所有随着数据库的大小增加,它们会变得显着慢。随着可以在内存中排序的数据大小的限制,以确保数据库Server.mysql的稳定性控制可以排序的最大数据量通过sort_buffer_size设置内存,而postgreesql使用work_mem变量.on两个系统,这些值通常小于10mb。因为这一点,要对大型数据集进行排序,数据库创建一个临时文件以一次为一个临时文件进行排序稍后将它们合并在一起。提交大小,需要许多读写操作。
简单的解决方案是使用具有序号的列。该列可以是现有的主键或为此目的添加的新列。查询在列值范围内使用随机数:
从存储库联盟选择地板(Orchan(*)*(count(*))+ 1)中选择楼层(随机(*))+ 1)从存储库联盟选择地板(随机()*(计数(*))+ 1)从存储库中)
可以进一步改进使用随机偏移的想法。在指定特定行并强制数据集没有间隙的情况下,将用于指示范围搜索的起点:
删除创建的间隙会导致不平衡。删除一些连续的记录将导致下一次记录的概率更高
一些随机值将导致比预期的较少的记录数(例如,随机值非常低)
最后一个方法是到目前为止的最佳方法。根据索引满足的范围搜索选择随机记录是有前途的。基于最后一种方法,解决方案需要具有以下属性:
选定的随机起始点必须能够导致所需的结果数量,与该值无关
数据库中有功能符合所有这些条件的功能。人们可以使用空间扩展来为二维空间中的每行分配随机值,从而为大量记录创建完全随机分发。只有几个记录,分布并不完美:
为PostgreSQL构建了以下解决方案,但可以很容易地应用于任何其他数据库。要使用空间功能,我们将列与空间数据类型添加到二维空间中的点,并更新所有先前的值随机值。要实现实现高效,我们还为此列创建了索引。
更改表存储库添加列随机性点;更新开票人设置随机= point(randul(),random());使用SPGIST(随机性)在存储库中创建索引Reposities_Randomisty;
利用数据库现在在二维空间中均匀地分发所有记录,可以查询数据。现在使用由&gt表示的k-college邻居(k-nn)算法来查找查询以查找随机值。 算子参考创建的二维空间中的随机点。虽然以下查询不包括任何进一步的条件来缩小结果集,但是可以这样做,并且不会在失败的前方法中更改随机分布 。 这种方法仍然快速,数百万条记录仍然始终少于1毫秒以执行。attabase优化有时非常困难,但是有可能是最复杂的问题的解决方案,你只需要创造创意。