当我使用ad-hoc SQL(例如,"SELECT foo FROM tablename"
)调用MSSQL数据库时,我可以为该调用提供批量大小。当我期望返回大量数据时,这非常有用。
在我的情况下,我有一个超过2亿行的表,而且我得到了所有这些。是的,我有理由成为像这样的大型奶牛。
我的数据库人员说,“嘿,停止使用临时SQL,在这里,使用这个漂亮的SP。它做同样的事情。”
所以我在mssql_execute()
函数调用中使用它,但在执行此操作时没有办法指定批量大小,因为mssql_query()
我不仅要做ini_set('memory_limit', '64G')
;为了完成这项工作,我也不得不出汗,因为SP呼叫需要花费半小时才能运行。一旦它运行,我可以在mssql_fetch_row()
上循环,没问题,但是这个初始调用是一个钉子![/ p>
一旦我完成了,我有一个占用57G内存的进程(在一个96G的盒子上),然后在80%的CPU上花费整整一个小时来放松和垃圾收集。是的,我可以杀死这个过程,但那是一个黑客攻击。
必须有更好的方法!
使用ad-hoc SQL,我调用批量大小为10,000行的mssql_query()
并处理它们,然后返回更多。然后,我可以做一些回音“是的,确实,我现在正在排$i
......”并且让我的偏执狂让一切顺利。
那么......如果我被迫使用我的数据库人员希望我使用的SP,那么这样做的恰当方法是什么?
答案 0 :(得分:0)
假设表有一个主键,我建议你让DB伙伴给存储过程添加2个参数,一个用于返回的行数,另一个用于起始键值。为初始批处理传递NULL,为每个后续批处理返回最后一个键值。这将提供有效的前向分页。例如:
CREATE PROCEDURE dbo.usp_select_tablename
@NumRows int
, @StartKey int = NULL
AS
IF @StartKey IS NULL
BEGIN
SELECT TOP(@NumRows) foo
FROM tableName
ORDER BY StartKey;
END
ELSE
BEGIN
SELECT TOP(@NumRows) foo
FROM tableName
WHERE Key > @StartKey
ORDER BY StartKey;
END;