MySQL single query benchmarking strategies - mysql

I have a slow MySQL query in my application that I need to re-write. The problem is, it's only slow on my production server and only when it's not cached. The first time I run it, it will take 12 seconds, then any time after that it'll be 500 milliseconds.
Is there an easy way to test this query without it hitting the query cache so I can see the results of my refactoring?

MySQL supports to prevent caching single queries. Try
SELECT SQL_NO_CACHE field_a, field_b FROM table;
alternatively you can diasble the query cache for the current session:
SET SESSION query_cache_type = OFF;
See http://dev.mysql.com/doc/refman/5.1/en/query-cache.html

To add to johannes's good answer, what I do is
RESET QUERY CACHE;
This has the slight added advantage of not requiring any changes to either the statements I'm executing or the connection.
A trivial thing to do is to alter the statement you're executing somehow, such as put a random number in a comment, because a queries are located in the cache only if they are byte-identical to some previous query.

Related

MySQL completely clearing cache

I am building a website in ASP.NET which is connected to a MySQL database.
I have a complex query and I have noticed that first time after a I re-start MySQL this query is slow (5-8 sec), following happens almost immediately (< ~1 sec).
I thought this had to do with data being cached by MySQL, so I tried to do a
FLUSH QUERY CACHE and even a RESET QUERY CACHE - but this seems not to affect the response-time of the query.
Any suggestion on how I can completely clear the cache without actually restarting the DB server.
You can use the SQL_NO_CACHE option.
Example:
SELECT SQL_NO_CACHE id, name FROM customer;
For more information, check the MySQL documentation for SQL Query Cache SELECT Options

Preventing a single query from appearing in slow query log

Is a way to prevent a single query from appearing in mysql slow query log?
One may actually disable logging before executing the query (by setting a global variable) and enable it back after the query, but this would prevent logging in other threads as well, which is not desirable.
Do you have any ideas?
In MySQL 5.1 and later, you can make runtime changes to the time threshold for which queries are logged in the slow query log. Set it to something ridiculously high and the query is not likely to be logged.
SET SESSION long_query_time = 20000;
SELECT ...whatever...
SET SESSION long_query_time = 2;
Assuming 2 is the normal threshold you use.
I don't know if you can prevet a single query from appearing in the slow query log, but you could use a grepped output from the query log. Having said that, if I remember correctly, every slow query is dumped as multiple lines so it would not be easy to grep it out, but not impossible.
mysqldumpslow has a "-g pattern" option to "Consider only queries that match the (grep-style) pattern." which may help in your situation.
I hope this helps.
Cheers
Tymek

Does MySQL store somehow the last querie(s)?

While working with MySQL and some really "performance greedy queries" I noticed, that if I run such a greedy query it could take 2 or 3 minutes to be computed. But if I retry the query immediately after it finished the first time, it takes only some seconds. Does MySQL store something like "the last x queries"?
The short answer is yes. there is a Query Cache.
The query cache stores the text of a SELECT statement together with the corresponding result that was sent to the client. If an identical statement is received later, the server retrieves the results from the query cache rather than parsing and executing the statement again. The query cache is shared among sessions, so a result set generated by one client can be sent in response to the same query issued by another client.
from here
The execution plan for the query will be calculated and re-used. The data can be cached, so subsequent executions will be faster.
Yes, depending on how the MySQL Server is configured, it may be using the query cache. This stores the results of identical queries until a certain limit (which you can set if you control the server) has been reached. Read http://dev.mysql.com/doc/refman/5.1/en/query-cache.html to find out more about how to tune your query cache to speed up your application if it issues many identical queries.

Mysql query run twice is much faster the second time even with SQL_NO_CACHE

I am trying to profile two different queries that do the same thing to find which one is faster. For testing, I have put SQL_NO_CACHE into both queries to prevent the query cache from messing up the timing.
Query A is consistently 50ms.
Query B is 100ms the first time it is run and 10ms if I run it a second time shortly after.
Why is Query B faster the second time? The query cache should not be speeding up the queries. Could it be that the first run of query B loads the data from disk into memory so that the second query is running in memory and faster? Is there a way to test this? I tried to test this myself by doing select * from the table before I ran Query B, but it still exhibited the same behavior. Is SQL_NO_CACHE perhaps not working to disable the query cache?
Query B looks something like this:
SELECT SQL_NO_CACHE foo,bar FROM table1 LEFT JOIN table2 ON table1.foo=table2.foo WHERE bar=1
Depending on the storage engine you're using, yes it is most probably being loaded from a data cache and not a query cache.
MyISAM provides no storage engine level caching for data, and only caches indexes. However, the operating system often serves up data from its own caches which may well be speeding up your query execution.
You can try benchmarking the query in a real scenario, just log that specific query to the database every time its executed (along with its execution time).
Depending on the size of your indexes and your table type, it may be that indexes are not in memory the first time the query is run. So MySQL will pull indexes into memory the first time the query is run, causing a significant slowdown. The next time, most of what MySQL needs may in memory, resulting in the performance gain.
Is your app making a connection and doing the authentication handshake on the first query? If so the 2nd query will already have an open/authenticated connection to execute from. Try running it a 3rd time and see if the 2nd and 3rd tries are close to the same time.

MySQL - force not to use cache for testing speed of query

I'm testing the speed of some queries in MySQL. The database is caching these queries making it difficult for me to get reliable results when testing how fast these queries are.
Is there a way to disable caching for a query?
System: MySQL 4 on Linux webhosting, I have access to PHPMyAdmin.
Thanks
Try using the SQL_NO_CACHE (MySQL 5.7) option in your query.
(MySQL 5.6 users click HERE )
eg.
SELECT SQL_NO_CACHE * FROM TABLE
This will stop MySQL caching the results, however be aware that other OS and disk caches may also impact performance. These are harder to get around.
Another alternative that only affects the current connection:
SET SESSION query_cache_type=0;
Any reference to current date/time will disable the query cache for that selection:
SELECT *,NOW() FROM TABLE
See "Prerequisites and Notes for MySQL Query Cache Use" # http://dev.mysql.com/tech-resources/articles/mysql-query-cache.html
There is also configuration option: query_cache_size=0
To disable the query cache at server startup, set the query_cache_size system variable to 0. By disabling the query cache code, there is no noticeable overhead. If you build MySQL from source, query cache capabilities can be excluded from the server entirely by invoking configure with the --without-query-cache option.
See http://dev.mysql.com/doc/refman/5.1/en/query-cache.html
You can also run the follow command to reset the query cache.
RESET QUERY CACHE
One problem with the
SELECT SQL_NO_CACHE * FROM TABLE
method is that it seems to only prevent the result of your query from being cached. However, if you're querying a database that is actively being used with the query you want to test, then other clients may cache your query, affecting your results. I am continuing to research ways around this, will edit this post if I figure one out.
I'd Use the following:
SHOW VARIABLES LIKE 'query_cache_type';
SET SESSION query_cache_type = OFF;
SHOW VARIABLES LIKE 'query_cache_type';
Using a user-defined variable within a query makes the query resuts uncacheable. I found it a much better indicator than using SQL_NO_CACHE. But you should put the variable in a place where the variable setting would not seriously affect the performance:
SELECT t.*
FROM thetable t, (SELECT #a:=NULL) as init;
Whilst some of the answers are good, there is a major caveat.
The mysql queries may be prevented from being cached, but it won't prevent your underlying O.S caching disk accesses into memory. This can be a major slowdown for some queries especially if they need to pull data from spinning disks.
So whilst it's good to use the methods above, I would also try and test with a different set of data/range each time, that's likely not been pulled from disk into disk/memory cache.
If you want to disable the Query cache set the 'query_cache_size' to 0 in your mysql configuration file . If its set 0 mysql wont use the query cache.
You must change SQL string. Because SQL string is a cache key.
For example, add a timestamp to a SQL comment.
Function for PHP:
function db_RunSQL($SQL, $NoCacheMode=false)
{
$SQL = (($NoCacheMode) ? '/*'.time().'*/ ' : '') . $SQL;
return mysqli_query(db_SavedConnect(), $SQL);
}