我有一张桌子,里面至少有一百万条记录。这些行是由一个自定义应用程序创建的,该应用程序读取多个 SharePoint 网站集并将项目 url 存储在表中。现在,由于我们以串行方式读取网站集,前几千行属于第一个网站集,接下来的几千行属于第二个网站集,依此类推。
我有另一个按顺序读取此表的应用程序。但是,这样我最终会向同一个网站集发送 HTTP 请求更长的时间。
我知道我可以从我的第二个应用程序的表格中获得随机结果。但是,这不是一个选择。我无法更改第二个应用程序的工作方式。
现在,问题是:如何获取表中的所有行,将它们洗牌并存储回表中?
更新:SQL Server 2008 R2 是我的数据库服务器
如果调用应用程序在其查询中明确设置特定顺序(如果您运行的是 MSSQL,则可以通过在应用程序执行其操作时运行探查器会话来检查这一点,其他 DMBS 将具有类似的日志记录选项)那么您将无能为力做,如果不是,你不能完全保证任何特定的订单。
如果没有给出明确的 ORDER BY 子句,那么数据将以正式“未定义”的顺序出现——这将是服务器发现最方便的顺序。对于单个表查询,这很可能是主键的顺序。在 MSSQL 中,如果你有一个聚簇索引,结果很可能会按照单个表查询的顺序出现。对于多表查询,它甚至更不明确,因为它取决于查询计划者选择哪种方式来获得你的结果(如果没有明确的索引提示,结果可能会随着时间的推移而变化,因为表中的数据平衡,由服务器保留、更改的索引统计信息)。
如果表没有聚簇索引或主键,则数据很可能以类似于数据插入顺序的任意顺序出现。在这种情况下,您可以尝试:
或者这可能会更快
上面的 NEWID() 是 MSSQL 返回 UUID 的函数,默认情况下它使用随机而不是顺序 ID - 在其他 DMBS 中,您应该找到可以使用的类似函数。请小心选择函数:例如,在 MSSQL 下,RAND() 函数每个查询计算一次,而不是每行计算一次,因此
SELECT * FROM somewhere ORDER BY RAND()
不会产生预期的效果(您可以通过运行类似的东西来了解原因SELECT RAND(), * FROM some_table
)。如果您使用的是 MSSQL(您的问题没有说明您的目标是哪个 DBMS)并且表上还没有聚簇索引,并且具有足够随机的列(例如 UUID 列)或者可以添加一个而不会打乱调用应用程序,您可以在其上创建一个聚集索引,这比上面的 SELECT INTO / DELETE / SELECT INTO 更快。但同样:如果应用程序以特定顺序明确要求结果,这将根本没有效果,否则可能不会有任何效果。
您不指定哪个数据库,但在 Oracle 中您可以通过以下方式执行此操作:
您需要在 TEMP 表空间中有足够的空间来处理排序。然后,如果您愿意,可以重命名表格
ORIG_TABLE
并将RAND_TABLE
它们交换过来。我认为不可能“就地”洗牌。