Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using $_SESSION to buffer/cache MySQL queries

I am developing a website. Currently, I'm on cheapo shared hosting. But a boy can dream and I'm already thinking about what happens with larger numbers of users on my site.

The visitors will require occasional database writes, as their progress in the game on the site is logged.

I thought of minimizing the queries by writing progress and other info live into the $_SESSION variable. And only when the session is destroyed (log out, browser close or timeout), I want to write the contents of $_SESSION to the database.

Questions:

  1. Is that possible? Is there a way to execute a function when the sessions is destroyed by timeout or closing of the browser?

  2. Is that sensical? Are a couple of hundred concurrent SQL queries going to be a problem for a shared server and is the idea of using $_SESSION as a buffer going to alleviate some of this.

like image 959
Ryan Avatar asked Apr 17 '12 13:04

Ryan


People also ask

How do I flush MySQL query cache?

You can defragment the query cache to better utilize its memory with the FLUSH QUERY CACHE statement. The statement does not remove any queries from the cache. The RESET QUERY CACHE statement removes all query results from the query cache. The FLUSH TABLES statement also does this.

How do I cache a MySQL query?

MySQL determines the queries to cache by examining the query_cache_type variable. Setting this value to 0 or OFF prevents caching or retrieval of cached queries. You can also set it to 1 to enable caching for all queries except for ones beginning with the SELECT SQL_NO_CACHE statement.

What is buffering in MySQL?

The change buffer is a special data structure that caches changes to secondary index pages when those pages are not in the buffer pool. The buffered changes, which may result from INSERT , UPDATE , or DELETE operations (DML), are merged later when the pages are loaded into the buffer pool by other read operations.

Why is MySQL query cache deprecated?

The query cache has been disabled-by-default since MySQL 5.6 (2013) as it is known to not scale with high-throughput workloads on multi-core machines. We considered what improvements we could make to query cache versus optimizations that we could make which provide improvements to all workloads.


2 Answers

Is there a way to execute a function when the sessions is destroyed by timeout or closing of the browser?

Yes, but it might not work the way you imagine. You can define your own custom session handler using session_set_save_handler, and part of the definition is supplying the destroy and gc callback functions. These two are invoked when a session is destroyed explicitly and when it is destroyed due to having expired, so they do exactly what you ask.

However, session expiration due to timeout does not occur with clockwork precision; it might be a whole lot of time before an expired session is actually "garbage-collected". In addition, garbage collection triggers probabilistically so in theory there is the chance that expired sessions will never be garbage collected.

Is that sensical? Are a couple of hundred concurrent SQL queries going to be a problem for a shared server and is the idea of using $_SESSION as a buffer going to alleviate some of this.

I really wouldn't do this for several reasons:

  • Premature optimization (before you measure, don't just assume that it will be "better").
  • Session might never be garbage collected; even if this doesn't happen, you don't control when they are collected. This could be a problem.
  • There is a possibility of losing everything a session contains (e.g. server reboots), which includes player progress. Players do not like losing progress.
  • Concurrent sessions for the same user would be impossible (whose "saved data" wins and remains persisted to the database?).

What about alternatives?

Well, since we 're talking about el cheapo shared hosting you are definitely not going to be in control of the server so anything that involves PHP extensions (e.g. memcached) is conditional. Database-side caching is also not going to fly. Moreover, the load on your server is going to be affected by variables outside your control so you can't really do any capacity planning.

In any case, I 'd start by making sure that the database itself is structured optimally and that the code is written in a way that minimizes load on the database (free performance just by typing stuff in an editor).

After that, you could introduce read-only caching: usually there is a lot of stuff that you need to display but don't intend to modify. For data that "almost never" gets updated, a session cache that you invalidate whenever you need to could be an easy and very effective improvement (you can even have false positives as regards the invalidation, as long as they are not too many in the grand scheme of things).

Finally, you can add per-request caching (in variables) if you are worried about pulling the same data from the database twice during a single request.

like image 184
Jon Avatar answered Oct 31 '22 20:10

Jon


It's not a good idea to write data when the session is destroyed. Since the session datas could be destroyed via a garbage collector configured by your hoster, you don't have any idea when the session is really closed until the user's cookie is out of date.

So... I suggest you to use either a shared memory (RAM) cache system like memcache (if your hoster offers it) or a disk based cache system.

By the way, if your queries are optimized, columns correctly indexed, etc., your shared hosting could take tons of queries at the "same time".

like image 22
noli Avatar answered Oct 31 '22 21:10

noli