Help - Search - Members - Calendar
Full Version: [HOWTO] Enable Query Caching in MySQL 4
The Planet Forums > System Administration > HOWTOs
Da`Nacho
How to enable Query Caching in MySQL 4.0.xx

One of the new features in MySQL 4 that has a lot of the geeks drooling is the new query caching process, which promises a substantial performance increase for many situations.

What does MySQL's Query Caching do?

Basically the query cache stores the text and result of a MySQL query so that if an identical query is made afterwards it doesn't have to be executed again repeatedly. Think of it as sort of a buffer for MySQL SELECT queries. (Yes, you uber geeks know it can get a little more involved but this is a simple howto)

This caching will quite literally 'kick @#!@#!@#!' on systems where tables don't change very often and the same queries are typically made over and over again. You can see how many of us are enthusiastic about it, can't you? icon_smile.gif

How do I enable it?

Easy, almost so easy that this howto is really needless.

Once you have MySQL 4 installed and running on your server, open your mysql configuration file with your favorite text editor (we will assume /etc/my.cnf and pico for this howto):

pico -w /etc/my.cnf

In the last line under the [mysqld] section add the following line:

set-variable = query_cache_size=16M

Here is what my entire [mysqld] section looks like as a point of reference:

[mysqld]
port = 3306
skip-locking
skip-innodb
set-variable = key_buffer=8M
set-variable = max_allowed_packet=2M
set-variable = table_cache=1024
set-variable = sort_buffer=2M
set-variable = join_buffer_size=1M
set-variable = record_buffer=1M
set-variable = myisam_sort_buffer_size=8M
set-variable = max_connections=300
set-variable = max_connect_errors=65535
set-variable = wait_timeout=14400
set-variable = thread_cache_size=256
set-variable = back_log=512
set-variable = connect_timeout=30
set-variable = tmp_table_size=4M
set-variable = query_cache_size=16M

What we've basically done is enabled the query cache and set the cache size all in one variable.

Now ctrl-x and answer Yes when pico asks if you want to save the file.

Now restart MySQL:

/etc/rc.d/init.d/mysql restart

If all goes well you should see:

#Starting mysqld daemon with databases from /var/lib/mysql

And MySQL should be up and running normally icon_smile.gif


As you can see above I've set my query cache size to 16 Megabytes, this may or may not be optimal for your system depending on how much ram you have and your situation. Details are still sketchy and I've not heard any formulas for calculating an optimal cache size yet, so experiment. Your box may like a much larger or much smaller value.


How can I verify that the data cache is enabled and functioning?

Easy! Do the following:

mysql -uroot -p

Enter your root mysql password and you will be in the CLI mysql client and able to execute queries to check on the status of the cache:

Check to see if the Query Cache is enabled:

mysql> SHOW VARIABLES LIKE 'mysql_query_cache';

Which should return:

CODE
+------------------+-------+

| Variable_name    | Value |

+------------------+-------+

| have_query_cache | YES   |

+------------------+-------+

1 row in set (0.00 sec)



Check to see how many queries are currently cached:

mysql> SHOW STATUS LIKE 'Qcache_queries_in_cache';

Returns:

CODE
+-------------------------+-------+

| Variable_name           | Value |

+-------------------------+-------+

| Qcache_queries_in_cache | 439   |

+-------------------------+-------+

1 row in set (0.00 sec)



Check to see how many hits the cache has had:

mysql> SHOW STATUS LIKE 'Qcache_hits';

Returns:

CODE
+---------------+-------+

| Variable_name | Value |

+---------------+-------+

| Qcache_hits   | 11762 |

+---------------+-------+

1 row in set (0.00 sec)



Check to see how much cache memory is currently free:

mysql> SHOW STATUS LIKE 'Qcache_free_memory';

Returns:

CODE
+--------------------+----------+

| Variable_name      | Value    |

+--------------------+----------+

| Qcache_free_memory | 15711224 |

+--------------------+----------+

1 row in set (0.00 sec)



You can also try atatus values like Qcache_inserts, Qcache_lowmem_prunes, Qcache_not_cached, Qcache_free_blocks, and Qcache_total_blocks. There is more info on all these here:

http://www.mysql.com/doc/en/Query_Cache_St...aintenance.html

Oh, you can leave the CLI MySQL client when you are done by hitting ctrl-c!

Well there you have it folks! Where do we go from here? Well I for one would like to know what the optimal query cache size value should be in different given situations. I'm anxious to see what all of your experiences are, good or bad. I hope this silly howto helped a couple of my fellow RackShack customers! icon_smile.gif
daveman692
Just enabled caching, hopefullt it speeds things up.
Ronny
What about those control panels that use mysql3? wil that breka nything
Da`Nacho
QUOTE
Originally posted by Ronny
What about those control panels that use mysql3? wil that breka nything


I wouldn't think so, since from what I understand the query caching scheme is pretty much transparent as far as applications are concerned. You could always try it and if it breaks anything turn it off.
Ronny
Can we use this caching system with mysql3?
daveman692
QUOTE
Originally posted by Ronny
Can we use this caching system with mysql3?

It is a new feature in MySQL 4, so no.
visuelz
You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near ''',
activity datetime NOT NULL default '0000-00-00 00:00


can someone help me?
ahbao
[fine now]
WrĊith
How would you go about enabling this on servers running Ensim? Doing a search on my server shows no file named my.cnf in the /etc/ directory. I do have one with that name in each of the individual /home/virtual/siteX/fst/etc/ directories, and one in the /etc/virtualhosting/templates/mysql/etc/ directory.

I tried just copying what was there (wasn't much just a couple of lines) and adding what you put in this thread, but it didn't make any difference. MySQL doesn't appear to be reading those configuration files.

I created a /etc/my.cnf file and added just what you put in this thread, but I don't really know if it's working. The first query you showed didn't yield what you had, but the others yielded something similar, albeit with different values.

Any thoughts??

What else should I have in the /etc/my.cnf file besides the [mysqld] section?
Da`Nacho
QUOTE
Originally posted by WrĊith
How would you go about enabling this on servers running Ensim?  Doing a search on my server shows no file named my.cnf in the /etc/ directory.  I do have one with that name in each of the individual /home/virtual/siteX/fst/etc/ directories, and one in the /etc/virtualhosting/templates/mysql/etc/ directory.


First of all you must be running MySQL 4.

If /etc/my.cnf doesn't exist, create it. Here are the contents of my own my.cnf, it is based on advice given in an 'optimize your mysql' thread here awhile back. You should just be able to create my.cnf and paste this in:

CODE
[mysqld]

datadir=/var/lib/mysql

socket=/var/lib/mysql/mysql.sock



[mysql.server]

user=mysql

basedir=/var/lib



[safe_mysqld]

err-log=/var/log/mysqld.log

pid-file=/var/run/mysqld/mysqld.pid



[mysqld]

port = 3306

skip-locking

skip-innodb

set-variable = key_buffer=8M

set-variable = max_allowed_packet=2M

set-variable = table_cache=1024

set-variable = sort_buffer=2M

set-variable = join_buffer_size=1M

set-variable = record_buffer=1M

set-variable = myisam_sort_buffer_size=8M

set-variable = max_connections=300

set-variable = max_connect_errors=65535

set-variable = wait_timeout=14400

set-variable = thread_cache_size=256

set-variable = back_log=512

set-variable = connect_timeout=30

set-variable = tmp_table_size=4M

set-variable = query_cache_size=8M



[safe_mysqld]

open_files_limit=8192



[mysqldump]

quick

set-variable = max_allowed_packet=16M



[myisamchk]

set-variable = key_buffer=16M

set-variable = sort_buffer=16M

set-variable = read_buffer=4M

set-variable = write_buffer=4M



[mysqlhotcopy]

interactive-timeout


Once you've created /etc/my.cnf and pasted the above in restart MySQL. MySQL *WILL* see your new my.cnf and read the configuration items contained within it. Note that if you don't have MySQL 4 installed the query_cache_size variable will simply be ignored.
ClayGP
Why did you decrease your query_cache_size to 8M in the most recent one?
Da`Nacho
QUOTE
Originally posted by ClayGP
Why did you decrease your query_cache_size to 8M in the most recent one?


Actually I copied that at a time when I was playing with cache sizes trying to see what was better. I since changed it back to 16M on my own Celeron 1.3 box because it seems to be the sweet spot sofar.

I really havent seen a set formula for calculating an optimum query cache size, I guess the query cache is just too new for that. icon_smile.gif
ClayGP
Ahh .. ok. Thanks! I'm on a Celeron 1.3 box as well .. but I have 1GB of RAM .. and some super busy forums. I think I'll set it to 16 for now and see how it goes..
DeMiNe0
root@hostparticle01 [~/mysql4]# mysql -uroot -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or g.
Your MySQL connection id is 1 to server version: 4.0.12

Type 'help;' or 'h' for help. Type 'c' to clear the buffer.

mysql> SHOW VARIABLES LIKE 'mysql_query_cache';
Empty set (0.00 sec)

mysql>







Thats what i got ^^^^
EgoH
QUOTE
Originally posted by DeMiNe0
root@hostparticle01 [~/mysql4]# mysql -uroot -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or g.
Your MySQL connection id is 1 to server version: 4.0.12

Type 'help;' or 'h' for help. Type 'c' to clear the buffer.

mysql> SHOW VARIABLES LIKE 'mysql_query_cache';
Empty set (0.00 sec)

mysql>

Thats what i got ^^^^


set-variable = query_cache_type=1
set-variable = query_cache_size=16M

Put that in the my.cnf, restart and it will shwo correctly.
SkyNet
QUOTE
Originally posted by DeMiNe0
root@hostparticle01 [~/mysql4]# mysql -uroot -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or g.
Your MySQL connection id is 1 to server version: 4.0.12

Type 'help;' or 'h' for help. Type 'c' to clear the buffer.

mysql> SHOW VARIABLES LIKE 'mysql_query_cache';
Empty set (0.00 sec)

mysql>
Thats what i got ^^^^


It should have been 'have_query_cache'.
But I would suggest you try:
mysql> SHOW VARIABLES LIKE '%query_cache%';

and

mysql> SHOW STATUS LIKE 'Qcache%';

instead. You get all of the variables and status information at the same time:


+-------------------+----------+
| Variable_name | Value |
+-------------------+----------+
| have_query_cache | YES |
| query_cache_limit | 1048576 |
| query_cache_size | 33554432 |
| query_cache_type | ON |
+-------------------+----------+

+-------------------------+----------+
| Variable_name | Value |
+-------------------------+----------+
| Qcache_queries_in_cache | 746 |
| Qcache_inserts | 764 |
| Qcache_hits | 5571 |
| Qcache_lowmem_prunes | 0 |
| Qcache_not_cached | 0 |
| Qcache_free_memory | 32496784 |
| Qcache_free_blocks | 1 |
| Qcache_total_blocks | 1506 |
+-------------------------+----------+
ClayGP
Why don't you guys just use phpMyAdmin?? So much easier. Just click on:

Show MySQL runtime information
JimmyGee
i have followed Da 'Nachos my.cnf and pretty much transferred the whole lot except for the 'set-variable = query_cache_size=16M' bit

so my my.cnf file looks like this

[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock

[mysql.server]
user=mysql
basedir=/var/lib

[safe_mysqld]
err-log=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

[mysqld]
port = 3306
skip-locking
skip-innodb
set-variable = key_buffer=8M
set-variable = max_allowed_packet=2M
set-variable = table_cache=1024
set-variable = sort_buffer=2M
set-variable = join_buffer_size=1M
set-variable = record_buffer=1M
set-variable = myisam_sort_buffer_size=8M
set-variable = max_connections=300
set-variable = max_connect_errors=65535
set-variable = wait_timeout=14400
set-variable = thread_cache_size=256
set-variable = back_log=512
set-variable = connect_timeout=30
set-variable = tmp_table_size=4M


[safe_mysqld]
open_files_limit=8192

[mysqldump]
quick
set-variable = max_allowed_packet=16M

[myisamchk]
set-variable = key_buffer=16M
set-variable = sort_buffer=16M
set-variable = read_buffer=4M
set-variable = write_buffer=4M

[mysqlhotcopy]
interactive-timeout


when i try and restart mysql using /etc/rc.d/init.d/mysqld restart it restarts fine without that line. I added each line one by one and restarted after each addition. The problem is when i put in
set-variable = query_cache_size=16M
and try to restart i get the following

Stopping MySQL: [ OK ]
Starting MySQL: [FAILED]

This seems to be the crucial line too so i dont know what im doing wrong there.

Im running a 1.7gig ensim pro/redhat package with 1 gig of ram.

Any suggestions? At the moment i am getting alot of traffic in my forums (200 people at a time) and its slowing this server right down to a point where its unbearable :/ so a quick fix would be appreciated

I previuosly made a couple of changes to php.ini, nothing too drastic just changed file upload limits to 50meg (3 or 4 variables in php.ini) and turned php_safe_mode off. Could any of this affect it?
newuser
sounds like you're using an older version of mysql.

only the more recent versions have query cache.

also, it would be a good idea to go into your mysql data dir and look at the err log.
JimmyGee
Were using mysql version 4.2.2, I'll check the error logs
jough
QUOTE
Originally posted by JimmyGee
Were using mysql version 4.2.2, I'll check the error logs


I think you mean you're using PHP 4.2.2

The latest version of mySQL is only 4.0.14 stable.

There is an alpha version of 4.1.0, but it's not recommended for production servers.

Make sure your mySQL version is 4.0.14, the latest stable version. I'll bet it isn't.

From the command line (logged in as root), type:

mysql --version

It will tell you the version.
sgtser
Hello all,

Great tutorial. A quick note :

Setting variables via set-variable is deprecated in MySQL 4+ :


http://www.mysql.com/doc/en/Option_files.html

"This is equivalent to --set-variable variable=value on the command-line. Please note that --set-variable is deprecated since MySQL 4.0; as of that version, program variable names can be used as option names. On the command line, just use --variable=value. In an option file, use variable=value."


So instead of something like this in your my.conf :

set-variable = record_buffer=1M

simply put :

record_buffer=1M etc...
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Invision Power Board © 2001-2010 Invision Power Services, Inc.