PARTITIONing on the PRIMARY KEY is usually useless.
With each partition having 20M rows and covering about 90 days, that is 222K rows per day, correct? And 2 seconds to SELECT all the rows from one day?
If your SELECT covers a range of, say, 2 day's worth, the query will scan about 444K rows, whether they are all in one partition or spread across two adjacent partitions. That is, 4 seconds for any 2 days.
You mentioned a 2 seconds for 1 day and 50 seconds for 365 days? The inconsistency is _probably_ due to caching differences.
Unlike some other vendors, there is no "Global" index on the table. What you have described so far is 12 partitions. Each partition is an independent InnoDB table, with its own PRIMARY KEY and any secondary keys. On top of that is the "real" table which is sort of a 'union' of those 12 tables.
A select against a partitioned table does:
1. "Pruning": Look at the WHERE clause against the PARTITION "KEY" (range-partitioned by a primary key (integer _time_)). Decide which partition(s) are needed.
2. One-by-one, send the select to those partition(s) and get partial results.
3. Collect the results, apply ORDER BY, etc.
Perhaps it is obvious now that there is _no_ advantage in a partitioned table that is partitioned on the PK versus having a non-partitioned table.
There are valid reasons for using PARTITIONing; you have not found one of them. Please provide more information about the application, the SHOW CREATE TABLE (in some flavor), and the main SELECTs.
It could be that...
* some other SELECT can take advantage of partitioning;
* some other partition key would be advantageous;
* you need to DELETE data after N months, and would like to do it efficiently via DROP PARTITION;
* something else.
If your table is "huge" in the sense that it is too biggger than innodb_buffer_pool_size, then some queries will necessarily be I/O-bound. I/O bound queries are much slower than queries that touch only cached blocks.
Some more discussion:
http://mysql.rjweb.org/doc.php/partitionmaint