如何选择一些行,例如"在5秒内获得尽可能多的行"?

Uğu*_*han 7 mysql sql database

目标是:在5秒后获得最多行数并且不会获得比加载行更多的行.目的不是创建超时.

几个月之后,我想也许这会起作用但它没有:

declare @d1 datetime2(7); set @d1=getdate();
select c1,c2 from t1 where (datediff(ss,@d1,getdate())<5)
Run Code Online (Sandbox Code Playgroud)

Jon*_*tre 27

虽然近年来关系数据库的趋势越来越多地转向基于成本的查询优化,但我并不知道RDBMS本身支持为查询指定最大成本(时间或I/O).

"只是让它超时并使用迄今为止收集的记录"的想法是一个有缺陷的解决方案.缺陷在于复杂查询可能花费前5秒在查询计划的子树上执行散列,以生成将由计划的后续部分使用的数据.所以5秒后,你可能仍然没有记录.

要在5秒内获得尽可能多的记录,您需要一个具有已知估计执行计划的查询,然后可以使用该查询来估计要请求的最佳记录数,以使查询运行时间接近5秒尽可能.换句话说,知道查询优化器估计它每秒可处理875条记录,您可以请求4,375条记录.查询有时会运行时间超过5秒,但随着时间的推移,您的平均执行时间应该接近5秒.

那么......如何实现这一目标?

在您的特定情况下,这是不可行的.这个问题是"已知的估计执行计划".为了使这项工作可靠,您需要一个具有已知执行计划的存储过程,而不是即席查询.由于您无法在您的环境中创建存储过程,因此这不是启动程序.但是,对于那些想要探索该解决方案的人来说,这是一篇在Oracle中实现这一概念的团队的学术论文. 我没有阅读完整的论文,但基于摘要,听起来他们的工作可以转换为任何具有基于成本的优化的RDBMS(例如MS SQL,MySQL等)

好的,那么在你的情况下你可以做些什么呢?

如果你不能以"正确"的方式做到这一点,那就用黑客来解决它.

我的建议:保留自己的"估算成本"统计数据.

提前做一些测试并估计通常可以在4秒内返回多少行.假设这个数字是18,000.

因此,您将查询限制为18,000行.但是,每次运行时都会跟踪执行时间,并保持最后50次执行的移动平均值.如果该平均值小于4.5秒,请将查询大小加1%并重置移动平均值.所以现在你的应用每次都要请求18,180行.经过50次迭代后,如果移动平均线低于4.5秒,则再次加1%.

如果您的移动平均线超过4.75秒,则减去1%.

随着时间的推移,此方法应收敛到针对特定查询/环境/等的优化N行解决方案.并且应该在条件改变时(缓慢但稳定地)进行调整(例如,高并发与低并发)

只有一个 - 划伤,两个 - 更多的东西......

  1. 作为一名DBA,我不得不说......任何查询都需要花费超过5秒的时间才会非常罕见.特别是,如果它是一个频繁运行并由前端应用程序使用的查询,那么绝对不应该运行5秒.如果确实有一个面向用户的查询无法在5秒内完成,那就表明数据库设计需要改进.

  2. Jonathan VM的绿色法律报告我曾经为一家公司工作,该公司仍然使用大型机应用程序,每天都会发出大量的绿条点阵打印报告.其中大多数都被忽略了,而且在使用的少数几个中,大多数都没有在第一页之外阅读.报告可能有数千行按降序帐户年龄排序......所有用户需要的是查看最老化的10个行.我的定律是:实际需要查看大量行的用例数量无限小.想想 - 真的想到 - 关于查询的用例,以及是否拥有大量和大量的记录确实是用户需要的.


jma*_*nes 5

你的while循环理念并不能完全解决问题.通过循环的第一次迭代可能需要超过5秒.此外,与您尝试仅使用单个查询进行检索相比,它可能会导致在分配的时间内检索的行数要少得多.

就个人而言,我不会试图解决这个问题.相反,我会做一些测试,并通过反复试验确定一些我有信心将在五秒钟内加载的记录.然后,我会在加载查询上放置一个LIMIT.

接下来,根据要求,我会将数据库调用的超时设置为5秒,或者只是有些调用超过时间限制的可能性.

最后,考虑到大多数查询的大多数现代硬件,您可以在五秒钟内返回大量的记录.如果这是你的意图,很难想象将所有数据返回到UI并仍然可以使用它.

-Jason