/ 中存储网

MySQL如何的绑定(Bind)变量和Query Cache缓存

2014-07-13 16:21:02 来源:中存储网

    在MySQL中并没有Shared Pool来共享SQL及其执行计划, 因此是否共享不是很重要, 在程序中是否使用绑定(Bind)变量也不是很重要. 事实上在目前的版本中, 只有Server Side的编程才能使用绑定变量, 而客户端的程序虽然用了绑定变量, 但实际是上只是被进行了文本替换, 最早我在MySQL的JDBC驱动说明上看到了这一点, 现在用Perl程序(asyncdata.pl)从Oracle向MySQL复制数据时(启动MySQL时指定--log选项)从SQL的日志文件中看到如下记录:

Query       DELETE FROM T_OBJECTS
WHERE OBJECT_ID='441766' AND 1=1
Query       DELETE FROM T_OBJECTS
WHERE OBJECT_ID='441767' AND 1=1
Query       DELETE FROM T_OBJECTS
WHERE OBJECT_ID='441768' AND 1=1

    而根据MySQL的解释, 使用真正的绑定变量时, SQL的日志文件应当记录如下:

Prepare  [1] SELECT ?
Execute  [1] SELECT 3

    而我找遍了整个日志文件, 也没有发现Prepare字样, 虽然我的Perl程序中调用了prepare方法. MySQL中另一个功能Query Cache则刚好是建立在不绑定的基础上的, 这个缓冲区会将最近执行过的SQL的结果存起来, 下同遇到同样的SQL(区分大小写的文本比较)时, 就直接将结果返回来, 但如果这个SQL下面的的表有数据变动, 则将再次执行, 这个功能默认是禁用(query_cache_size的默认值为0)的, 估计现实生活中, 这样的应用少. 看起来象如下:

my (%qcache);

if (query_cache_size)
{
    if (exists $qcache{SQL})
    {
        return
$qcache{SQL}
    }
    else
    {
        my $rows =
mysql_execute(SQL);
        $qcache{SQL} =
$rows;
        return $rows;
    }
}
else
{
    return mysql_execute(SQL);
}

    其实MySQL中有内存表了, 完全可以不用这个功能. 对于Query Cache, MySQL提供了query_cache_type变量来控制发送到数据库的SQL是否进行Cache, 有三个值:

0, 对SQL语句不进行Cache.

1, 对于有SQL_NO_CACHE提示的SQL不进行Cache.

2, 仅对于有SQL_CACHE进示的SQL进行Cache.

    这个设计比较先进, 不过最好加上一个对表进行不进行Cache的控制, 如果指定某个表Cache则对所有只访问这个表的SQL进行Cache, 这样可能要对DBA方便很多, 否则我们得一条一条地更改SQL语句啊. 不知道有没有用过这个功能的人? 谈谈感想?