Mysql 在执行SELECT语句parse,execute sql以前会先到QC里面查看该sql是否已经被cache住了,如果是被QC住了,则没有必要再进行Parse和execute,直接返回结果就OK了,那具体是如何实现的呢?
1. The client sends the SQL statement to the server.
2. The server checks the query cache. If there’s a hit, it returns the stored result from the cache; otherwise, it passes the SQL statement to the next step.
3. The server parses, preprocesses, and optimizes the SQL into a query execution plan.
4. The query execution engine executes the plan by making calls to the storage engine API.
5. The server sends the result to the client
在sql_parse.cc/mysql_parse的代码有这样一句注释
Warning.
The purpose of query_cache_send_result_to_client() is to lookup the
query in the query cache first, to avoid parsing and executing it.
So, the natural implementation would be to:
- first, call query_cache_send_result_to_client,
- second, if caching failed, initialise the lexical and syntactic parser.
在sql parsing和executing之前,会调用
query_cache_send_result_to_client()函数去qc里面查找,如果找到就可以避免之后的parsing和executing。当然,如果缓存查找没找到,则会调用解析器进行相关的解析
在执行的过程中,会进行一系列的检查,包括:
1.QC是否被lock
2.query_cache_type是否设置禁用(0)
3.是否没有开启QC(query_cache_size=0)
4.是否是带有SQL_NO_CACHE的sql
5.select语句是否书写正确
在检查没有问题之后,下面的执行流程会对QC加锁
STRUCT_LOCK(&structure_guard_mutex);
structure_guard_mutex是个pthread_mutex_t 类型的全局共享锁。对该锁的解释如下:
/*
The following mutex is locked when searching or changing global
query, tables lists or hashes. When we are operating inside the
query structure we locked an internal query block mutex.
LOCK SEQUENCE (to prevent deadlocks):
1. structure_guard_mutex
2. query block (for operation inside query (query block/results))
*/
当我们执行query或者改变table lists或者hash桶的结构,会拥有该排它锁。当我们试图操作内部的query 结构的时候,会得到该锁。
可以看到我们在使用QC的时候,如果有其他查询也在使用,那么QC是不发挥作用的。
可见在并发很大的表(包括select和dml/ddl操作都会造成QC的lock contention)
sql需要的最少block在QC的分配
一个最简单的sql(只有一个table)也最少需要3个block,一个保存query text,一个保存query result,每个table需要一个block.当然table block是可以在session间共享的。文档的关于QC block分配的原文如下:
Every cached query requires a minimum of two blocks (one for the query text and one or more for the query results). Also, every table that is used by a query requires one block. However, if two or more queries use the same table, only one table block needs to be allocated.
几个常见的mysql操作对QC的影响:
Flush Query Cache:进行QC的碎片整理,提高QC的利用率,不会移走任何的queries
Flush tables:会将QC的queries全部remove掉
Reset Query Cache:会将QC的queries全部remove掉
阅读(1467) | 评论(0) | 转发(0) |