Fast way to split primary key into ranges
You can use NTILE and a CTE to produce a specified number of buckets of roughly equal size from your table. Example below with ~590,000 rows takes 1 second to run the query.

Setup:

CREATE TABLE RangeQuery (ID INT IDENTITY(1,1) PRIMARY KEY CLUSTERED,
    Val INT)
GO

INSERT INTO RangeQuery (Val)
SELECT 1
GO 590000

SELECT COUNT(*) FROM RangeQuery


Query:

;WITH CTE AS (
    SELECT ID, NTILE(20) OVER (ORDER BY ID ASC) AS [Range]
    FROM RangeQuery
)

SELECT [Range] AS [Bucket],
    MIN(ID) AS FirstID, 
    MAX(ID) AS LastID, 
    COUNT(ID) AS [RowCount]
FROM CTE
GROUP BY [Range]


Results:

Bucket  FirstID     LastID      RowCount
----------------------------------------
1       1           29919       29919
2       29920       59838       29919
3       59839       89757       29919
4       89758       119676      29919
5       119677      149595      29919
6       149596      179513      29918
7       179514      209431      29918
8       209432      239349      29918
9       239350      269267      29918
10      269268      299185      29918
11      299186      329103      29918
12      329104      359021      29918
13      359022      388939      29918
14      388940      418857      29918
15      418858      448775      29918
16      448776      478693      29918
17      478694      508611      29918
18      508612      538529      29918
19      538530      568447      29918
20      568448      598365      29918