I have bad news for you. What you want to do is going to be a lot harder than you were anticipating.
Most databases implement much of the ANSI SQL standard, but they do not implement all parts of it, especially for something more advanced like window functions. Some database platforms don't even support the
LIMIT construct that you used. You'll need to prepare for writing different code for each database platform that you support.
It is unlikely that the database that you connect to will have an index on every column of every table. You will need some kind of control over the schema of the database that you're querying to get a schema that allow for reasonable performance of the queries that you want to run. Even then, a standard b-tree index doesn't allow for fast computations of percentiles.
The query optimizers of each database platform work in significantly different ways. A query that is fast on one platform may be slow on another. Consider the following simple query against an indexed ID column:
SELECT MIN(ID), MAX(ID)
That query used to be extremely fast on SQL Server but would require two table scans on Oracle (newer versions of Oracle may have improved the query optimizer to no longer need the table scans). That query is significantly simpler than yours. I would not expect the approach that you used in the question to perform well on most platforms. I changed your syntax to one supported by SQL Server and the query didn't finish after six minutes against a table with about six million rows.
You should also consider relaxing the problem statement to allow for approximate results. If the goal is to split the data into parts and to process each part on a different system, then you probably don't need to send exactly 10% of the table to each system. Allowing for approximate results will greatly improve the performance of the query for some approaches, especially if the target tables are very large.
I suggest changing the question you asked to something resembling the following: "For database platform X, how can I compute fast (define fast) quantiles for a table with Y rows under Z isolation level?" With that type of question, a database expert for that platform may be able to help you. However, some platforms may not allow for an answer to be calculated as quickly as you'd like due to limitations of those platforms.
To give you an idea of what a well-performing solution would look like, I'll provide an example solution for the following question: "For database platform SQL Server, how can I compute quantiles for a table with 6.5 M rows under a SERIALIZABLE isolation level within 1 second?"
First I'll add 6.5 million rows to a table with a clustered columnstore index:
CREATE TABLE part_test (
ID1 BIGINT NOT NULL,
ID2 BIGINT NOT NULL,
ID3 VARCHAR(3) NOT NULL,
ID4 VARCHAR(10) NOT NULL,
ID5 DATETIME NOT NULL,
INDEX CCI CLUSTERED COLUMNSTORE
INSERT INTO part_test WITH (TABLOCK)
SELECT RN, RN % 100000, LEFT(CAST(NEWID() AS VARCHAR(40)), 3), REPLICATE(CHAR(RN % 60 + 10), 10), DATEADD(SECOND, RN, GETDATE())
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) RN
FROM master..spt_values t1
CROSS JOIN master..spt_values t2
OPTION (MAXDOP 1);
The reason I specified the SERIALIZABLE isolation level is it allows me to split the query up into two parts. I found it to be much easier to write fast code to solve this problem by using two queries. While the queries are running, no other process will be able to modify the data in the table. You need to decide if that's acceptable or not. Here is one method of calculating the percentiles:
DECLARE @CNT BIGINT, @MIN BIGINT, @MAX BIGINT;
SELECT @CNT = COUNT_BIG(*), @MIN = MIN(ID1), @MAX = MAX(ID1)
FROM part_test WITH (TABLOCK, SERIALIZABLE);
SELECT TOP (9) ID1
SELECT ID1, ROW_NUMBER() OVER (ORDER BY ID1) RN
FROM part_test WITH (TABLOCK)
WHERE RN % (@CNT / 10) = (@CNT / 10) - 1 -- math may not be exactly right here, but it's just a proof of concept
ORDER BY ID1
UNION ALL SELECT @MIN
UNION ALL SELECT @MAX
ORDER BY ID1;
That query finishes in about 200 ms on my 8 CPU core desktop. It's important to understand that this approach does a sort. Performance will get worse as the table gets more rows, especially if the sort cannot be performed in memory. As the table size gets bigger, a completely different strategy may perform better. That's one of the reasons that I mentioned that allowing for approximate results may help you.
It's also important to understand that the approach that I used is very specific to SQL Server. It's great if something like this meets your needs for SQL Server, but the solution for other database platforms will likely look significantly different from it.