I would appreciate if someone could explain how is it possible MySQL is not churning with a large table on default config.
note: I don't need advice how to increase the memory, improve the performance or migrate etc. I want to understand why it is working and performing well.
I have the following table:
CREATE TABLE `daily_reads` (
  `a` varchar(32) NOT NULL DEFAULT '',
  `b` varchar(50) NOT NULL DEFAULT '',
  `c` varchar(20) NOT NULL DEFAULT '',
  `d` varchar(20) NOT NULL DEFAULT '',
  `e` varchar(20) NOT NULL DEFAULT '',
  `f` varchar(10) NOT NULL DEFAULT 'Wh',
  `g` datetime NOT NULL,
  `PERIOD_START` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `i` decimal(16,3) NOT NULL,
  `j` decimal(16,3) NOT NULL DEFAULT '0.000',
  `k` decimal(16,2) NOT NULL DEFAULT '0.00',
  `l` varchar(1) NOT NULL DEFAULT 'N',
  `m` varchar(1) NOT NULL DEFAULT 'N',
  PRIMARY KEY (`a`,`b`,`c`,`PERIOD_START`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
It is running on a VM with 1 CPU Core, 6GB RAM, CentOS 7 (have very limited access to that VM).
It is running on a default MySQL config with 128MB buffer pool (SELECT @@innodb_buffer_pool_size/1024/1024)
DB size is ~96GB, ~560M rows in the 'reads' table, ~710M rows with other tables.
select database_name, table_name, index_name, stat_value*@@innodb_page_size
from mysql.innodb_index_stats where stat_name='size';
PRIMARY: 83,213,500,416 (no other indexes)
I get like ~500K reads/month and writes are done only as part of an ETL process directly from Informatica to the DB (~ 75M writes/month).
The read queries are called only via stored procedure:
CALL sp_get_meter_data('678912345678', '1234567765432', '2017-01-13 00:00:00', '2017-05-20 00:00:00');
// striped out the not important bits:
...
SET daily_from_date = DATE_FORMAT(FROM_DATE_TIME, '%Y-%m-%d 00:00:00');
SET daily_to_date = DATE_FORMAT(TO_DATE_TIME, '%Y-%m-%d 23:59:59');
...
SELECT
    *
FROM
    daily_reads
WHERE
    A = FRIST_NUMBER
    AND
    B = SECOND_NUMBER
    AND
    daily_from_date <= PERIOD_START
    AND
    daily_to_date >= PERIOD_START
ORDER BY
    PERIOD_START ASC;
My understanding of InnoDB is quite limited, but I thought I need to fit all indexes into memory to do fast queries. The read procedure takes only a few milliseconds. I thought it is not technically possible to query 500M+ tables fast enough on a default MySQL config...?
What am I missing?
note: I don't need advice how to increase the memory, improve the performance or migrate etc. I want to understand why it is working and performing well.