Sorry about the unfitting first answer - I obviously was too tired yesterday and misunderstood your question.
While using connection pools would help with the overall performance of the application, there are most probably other measures to take first:
MysqlTuner suggests valid options to set:
query_cache_limit (> 1M, or use smaller result sets)
join_buffer_size (> 1.0M, or always use indexes with JOINs)
innodb_log_file_size should be (=528M) if possible, so InnoDB total log files size equals to 25% of buffer pool size.
Also make sure the
mysqld.log gets rotated regularly and check for warnings/errors in there. You might start with deleting it and restarting the mysqld, then see what errors/warnings will get printed back in there from here on.
You could test if lowering the
innodb_buffer_pool_size to 1G (
innodb_buffer_pool_instances to 1 affects the performance negatively. According to the mysqltuner, there are only 254.3M of data in the buffer - so you would have enough room to grow.
The suggestion by @tero-kilkanen might be worth a shot, too. Though as there only were 58 out of 19K queries missing a matching index, I don't think this will yield much of a performance boost. But check the indexes for their sanity and included keys anyway.
To get rid of the warning, that your mysqld might use more than the installed amount of RAM, you should lower the
max_connections to a sane number: 20 - 30. Your application used 4 at the most during the uptime of he mysqld.
The maximum amount of memory to be assigned by mysqld is calculated rougly by multiplying the
max_connections (440) with the cache assigned per connection (mostly sort_buffer_size plus some smaller ones) and then adding the global buffers (i.e.
innodb_buffer_pool_size) to it. While 18.5MB per connection sounds not too much (it isn't) - multiplying it by 440 amounts to 8GB on their own.
As your application mainly uses read statements (99%) adding caching on the application side might reduce the overall load on the database and increase performance on the frontend side noticably.
Regularly queried values which rarely change at all (frontend user tables for instance) might be cached. Then you could invalidate the cache when editing student/parent users and their permissions.
If you still encounter problems, run the mysqld and application for a longer time before running mysqltuner. 1-3 days should yield better suggestions due to a more accurate usage profile.