点击这里给我发消息 点击这里给我发消息
首页 > 行业资讯 > MSSQL>详细内容

浅谈MySQL数据库优化

添加时间:2013-12-6
    相关阅读: 页面 数据库 程序 SQL Windows AI 优化
副标题#e#

我们在前面已经简单介绍了一些MYSQL数据库的基本操作,这一章我们将针对MYSQL数据库管理员详细介绍下MYSQL数据库的优化问题。

1 优化MySQL服务器

1.1 MYSQL服务器系统变量

我们在前面的章节中曾经讲到过MYSQL服务器的一些基本管理,这里我们再对MYSQL服务器的服务器变量和状态变量做个简单介绍。

查询MYSQL服务器系统变量:
C:\Program Files\MySQL\MySQL Server 5.0\bin> mysqld --verbose –help
通过mysqladmin命令来查询MYSQL服务器系统变量:
C:\Program Files\MySQL\MySQL Server 5.0\bin>mysqladmin -uroot -p variables > d:\init.txt
Enter password: ******

Init.txt部分内容:
+---------------------------------+----------------------------------------------------------------+
| Variable_name                   | Value                                                          |
+---------------------------------+----------------------------------------------------------------+
| auto_increment_increment        | 1                                                              |
| auto_increment_offset           | 1                                                              |
| automatic_sp_privileges         | ON                                                             |
| back_log                        | 50

…………
| version_compile_machine         | ia32                                                           |
| version_compile_os              | Win32                                                          |
| wait_timeout                    | 28800                                                          |
+---------------------------------+----------------------------------------------------------------+


获得MYSQL实际使用的服务器系统变量:
mysql> show variables;
利用like参数来显示具体的服务器系统变量:
mysql> show variables like 'init_connect%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| init_connect  |       |
+---------------+-------+
1 row in set (0.00 sec)

调整MYSQL服务器的系统变量

mysqld服务器维护两种变量。全局变量影响服务器的全局操作。会话变量影响具体客户端连接相关操作。服务器启动时,将所有全局变量初始化为默认值。可以在选项文件或命令行中指定的选项来更改这些默认值。服务器启动后,通过连接服务器并执行SET GLOBAL var_name语句可以更改动态全局变量。要想更改全局变量,必须具有SUPER权限。

方法一:
mysql> SHOW VARIABLES LIKE 'query_cache_size';
+------------------+----------+
| Variable_name    | Value    |
+------------------+----------+
| query_cache_size | 23068672 |
+------------------+----------+
1 row in set (0.01 sec)

mysql> SET GLOBAL query_cache_size = 31457280;
Query OK, 0 rows affected (0.00 sec)

mysql> SHOW VARIABLES LIKE 'query_cache_size';
+------------------+----------+
| Variable_name    | Value    |
+------------------+----------+
| query_cache_size | 31457280 |
+------------------+----------+
1 row in set (0.00 sec)


方法二:

mysql> show variables like 'query_cache_size%';
+------------------+----------+
| Variable_name    | Value    |
+------------------+----------+
| query_cache_size | 31457280 |
+------------------+----------+
1 row in set (0.00 sec)

mysql> SET @@global.query_cache_size = 20971520;
Query OK, 0 rows affected (0.09 sec)

mysql> show variables like 'query_cache_size%';
+------------------+----------+
| Variable_name    | Value    |
+------------------+----------+
| query_cache_size | 20971520 |
+------------------+----------+
1 row in set (0.00 sec)

mysql> select @@query_cache_size;
+--------------------+
| @@query_cache_size |
+--------------------+
|           20971520 |
+--------------------+
1 row in set (0.06 sec)

mysqld服务器还为每个客户端连接维护会话变量。连接时使用相应全局变量的当前值对客户端会话变量进行初始化。客户可以通过SET [SESSION] var_name语句来更改动态会话变量。设置会话变量不需要特殊权限,但客户可以只更改自己的会话变量,而不更改其它客户的会话变量。

mysql> SET sort_buffer_size = 10 * 1024 * 1024;
Query OK, 0 rows affected (0.08 sec)

mysql> show variables like 'sort_buffer%';
+------------------+----------+
| Variable_name    | Value    |
+------------------+----------+
| sort_buffer_size | 10485760 |
+------------------+----------+
1 row in set (0.00 sec)

注意,当使用启动选项设置变量时,变量值可以使用后缀K、M或G分别表示千字节、兆字节或gigabytes。例如,下面的命令启动服务器时的键值缓冲区大小为16 megabytes:
C:\ProgramFiles\MySQL\MySQL Server 5.0\bin>mysqld--key_buffer_size=16M
后缀的大小写美关系;16M和16m是同样的。

运行时,使用SET语句来设置系统变量。此时,不能使用后缀,但值可以采取下列表达式:
mysql> SET sort_buffer_size = 10 * 1024 * 1024;

1.2 MYSQL服务器状态变量

mysqladmin查看服务器状态变量(动态变化):

C:\Program Files\MySQL\MySQL Server 5.0\bin>mysqladmin -uroot -p extended-status

Enter password: ******
+-----------------------------------+----------+
| Variable_name                     | Value    |
+-----------------------------------+----------+
| Aborted_clients                   | 0        |
| Aborted_connects                  | 3        |
| Binlog_cache_disk_use             | 0        |
| Binlog_cache_use                  | 0        |
| Bytes_received                    | 2664     |
| Bytes_sent                        | 96723    |
| Com_admin_commands                | 0        |
| Com_alter_db                      | 0        |
| Com_alter_table                   | 0        |
| Com_analyze                       | 0        |


该命令和下面命令等效:
//获得MYSQL服务器的统计和状态指标
mysql> show status;
+-----------------------------------+----------+
| Variable_name                     | Value    |
+-----------------------------------+----------+
| Aborted_clients                   | 0        |
| Aborted_connects                  | 3        |
| Binlog_cache_disk_use             | 0        |
| Binlog_cache_use                  | 0        |
| Bytes_received                    | 765      |
| Bytes_sent                        | 80349    |
| Com_admin_commands                | 0        |
| Com_alter_db                      | 0        |
| Com_alter_table                   | 0        |
| Com_analyze                       | 0        |

//刷新MYSQL服务器状态变量
mysql> show status like 'Bytes_sent%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Bytes_sent    | 53052 |
+---------------+-------+
1 row in set (0.00 sec)

mysql> flush status;
Query OK, 0 rows affected (0.00 sec)

mysql> show status like 'Bytes_sent%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Bytes_sent    | 11    |
+---------------+-------+
1 row in set (0.00 sec)

1.3 MYSQL服务器关键参数优化

key_buffer_size

这个参数对MyISAM表来说非常重要。如果我们的系统只是使用MyISAM表,可以把它设置为操作系统物理内存的 30-40%。取决于索引大小、数据量以及负载,MyISAM表会使用操作系统的缓存来缓存数据,因此需要留出部分内存给它们,很多情况下数据比索引大多了。尽管如此,需要总是检查是否所有的 key_buffer都被利用了 。如果*.MYI 文件只有 1GB,而 key_buffer 却设置为 4GB 的话就太浪费了。如果没有MyISAM表,那么也保留16-32MB 的 key_buffer_size 以供临时表索引使用,也就是不要禁止这个参数(设置为0)。

我们下边给出几个比较重要的MYSQL服务器参数,这里我们着重讲述InooDB引擎相关的参数。

innodb_buffer_pool_size

该参数对Innodb表来说非常重要。Innodb相比MyISAM表对缓冲更为敏感。MyISAM可以在默认的 key_buffer_size 设置下运行的可以,然而Innodb在默认的innodb_buffer_pool_size 设置下却跟蜗牛似的。由于Innodb把数据和索引都缓存起来,无需留给操作系统太多的内存,因此如果只需要用Innodb并且系统地数据量非常大的话则可以设置它高达 70-80% 的可用内存。

有些总结中说到,在 Linux x86 上不要把内存设置太高,内存使用下面的加起来不要超过2G,这个我们提醒一下。

innodb_buffer_pool_size+ key_buffer_size+
max_connections*(sort_buffer_size+read_buffer_size+binlog_cache_size)
+ max_connections*2MB < 2G

innodb_additional_mem_pool_size

InnoDB 用来存储数据字典(data dictionary)信息和其它内部数据结构(internal data structures)的存储器组合(memory pool)大小。理想的值为 2M,如果有更多的表你就需要在这里重新分配。如果 InnoDB 用尽这个池中的所有内存,它将从操作系统中分配内存,并将错误信息写入 MySQL 的错误日志中。在 my.ini 中以数字格式设置。

innodb_log_file_size

在高写入负载尤其是大数据集的情况下很重要。这个值越大则性能相对越高,但是要注意到可能会增加恢复时间。我们经常设置为 64-512MB,根据服务器文件系统大小而异。

innodb_log_buffer_size

默认的设置在中等强度写入负载以及较短事务的情况下,服务器性能还可以。如果存在更新操作峰值或者负载较大,就应该考虑加大它的值了。如果它的值设置太高了,可能会浪费内存 -- 它每秒都会刷新一次,因此无需设置超过1秒所需的内存空间。通常 8-16MB 就足够了。越小的系统它的值越小。

innodb_flush_log_at_trx_commit

是否为Innodb比MyISAM慢1000倍而头大?看来也许你忘了修改这个参数了。默认值是 1,这意味着每次提交的更新事务(或者每个事务之外的语句)都会刷新到磁盘中,而这相当耗费资源。很多应用程序,尤其是从 MyISAM转变过来的那些,把它的值设置为 2 就可以了,也就是不把日志刷新到磁盘上,而只刷新到操作系统的缓存上。日志仍然会每秒刷新到磁盘中去,因此通常不会丢失每秒1-2次更新的消耗。如果设置为 0 就快很多了,不过也相对不安全了 -- MySQL服务器崩溃时就会丢失一些事务。设置为 2 只会丢失刷新到操作系统缓存的那部分事务。

innodb_log_files_in_group

日志组中的日志文件数目。InnoDB 以环型方式(circular fashion)写入文件。数值 3 被推荐使用。在 my.ini 中以数字格式设置。

innodb_lock_wait_timeout

在回滚(rooled back)之前,InnoDB 事务将等待超时的时间(单位 秒)。InnoDB 会自动检查自身在锁定表与事务回滚时的事务死锁。如果使用 LOCK TABLES 命令,或在同一个事务中使用其它事务安全型表处理器(transaction safe table handlers than InnoDB),那么可能会发生一个 InnoDB 无法注意到的死锁。在这种情况下超时将用来解决这个问题。这个参数的默认值为 50 秒。在 my.ini 中以数字格式设置。

table_cache

打开一个表的开销可能很大。例如MyISAM把MYI文件头标志该表正在使用中。你肯定不希望这种操作太频繁,所以通常要加大缓存数量,使得足以最大限度地缓存打开的表。它需要用到操作系统的资源以及内存,对当前的硬件配置来说当然不是什么问题了。如果你有200多个表的话,那么设置为 1024 也许比较合适(每个线程都需要打开表),如果连接数比较大那么就加大它的值。我曾经见过设置为 100,000 的情况。

tmp_table_size

如果内存内的临时表超过该值,MySQL自动将它转换为硬盘上的MyISAM表,所以我们在前边讲述key_buffer_size的时候曾经说过即使我们的系统中没有MyISAM表也要保留key_buffer_size的值为16-32M。如果系统有很多GROUP BY查询并且有大量内存,则可以增加tmp_table_size的值。

thread_cache

线程的创建和销毁的开销可能很大,因为每个线程的连接/断开都需要。我通常至少设置为 16。如果应用程序中有大量的跳跃并发连接并且 Threads_Created的值也比较大,那么我就会加大它的值。它的目的是在通常的操作中无需创建新线程。

query_cache

如果你的应用程序有大量读,而且没有应用程序级别的缓存,那么这很有用。不要把它设置太大了,因为想要维护它也需要不少开销,这会导致MySQL变慢。通常设置为 32-512Mb。设置完之后最好是跟踪一段时间,查看是否运行良好。在一定的负载压力下,如果缓存命中率太低了,就启用它。

max_connections

允许的并行客户端连接数目。根据系统的连接数来决定该参数的大小。

sort_buffer

就像你看到的上面这些全局表量,它们都是依据硬件配置以及不同的存储引擎而不同,但是会话变量通常是根据不同的负载来设定的。如果你只有一些简单的查询,那么就无需增加 sort_buffer_size 的值了,尽管你有 64GB 的内存。搞不好也许会降低性能。我通常在分析系统负载后才来设置会话变量。

innodb_file_io_threads

InnoDB 中的文件 I/O 线程。 通常设置为 4,但是在 Windows 下可以设定一个更大的值以提高磁盘 I/O。在 my.ini 中以数字格式设置。

innodb_fast_shutdown

如果把这个参数设置为0,InnoDB在关闭之前做一个完全净化和一个插入缓冲合并。这些操作要花几分钟时间,设置在极端情况下要几个小时。如果你设置这个参数为1,InnoDB在关闭之时跳过这些操作。默认值为1。如果你设置这个值为2 (在Netware无此值), InnoDB将刷新它的日志然后冷关机,仿佛MySQL崩溃一样。已提交的事务不会被丢失,但在下一次启动之时会做一个崩溃恢复。

innodb_max_dirty_pages_pct

这是一个范围从0到100的整数。默认是90。InnoDB中的主线程试着从缓冲池写页面,使得脏页(没有被写的页面)的百分比不超过这个值。如果你有SUPER权限,这个百分比可以在服务器运行时按下面来改变:
SET GLOBAL innodb_max_dirty_pages_pct = value;

innodb_thread_concurrency

InnoDB试着在InnoDB内保持操作系统线程的数量少于或等于这个参数给出的限制。如果有性能问题,并且SHOW INNODB STATUS显示许多线程在等待信号,可以让线程“thrashing” ,并且设置这个参数更小或更大。如果你的计算机有多个处理器和磁盘,你可以试着这个值更大以更好地利用计算机的资源。一个推荐的值是系统上处理器和磁盘的个数之和。值为500或比500大会禁止调用并发检查。默认值是20,并且如果设置大于或等于20,并发检查将被禁止。

THREAD_STAC

每个线程的堆栈大小。用crash-me测试检测出的许多限制取决于该值。 默认值足够大,可以满足普通操作

2 一个函数调试工具

如果我们的问题只是与具体MySQL表达式或函数有关,我们可以使用mysql客户程序所带的BENCHMARK()函数执行定时测试。其语法为:
BENCHMARK(loop_count,expression)

mysql> SELECT BENCHMARK(1000000,1+1);
+------------------------+
| BENCHMARK(1000000,1+1) |
+------------------------+
|                      0 |
+------------------------+
1 row in set (0.13 sec)

mysql> set autocommit = 0;
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT BENCHMARK(1000000,1+1);
+------------------------+
| BENCHMARK(1000000,1+1) |
+------------------------+
|                      0 |
+------------------------+
1 row in set (0.03 sec)

本文作者: #p#副标题#e#

3 SELECT优化

3.1 MYSQL数据库的SQL执行计划解释器

EXPLAIN tbl_name

或者如下:

EXPLAIN [EXTENDED] SELECT select_options

EXPLAIN tbl_name是DESCRIBE tbl_name或SHOW COLUMNS FROM tbl_name的一个同义词。
mysql> explain a;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id    | int(11) | YES  | UNI | NULL    |       |
+-------+---------+------+-----+---------+-------+
1 row in set (0.02 sec)

mysql> explain t;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int(11)     | NO   | PRI | 0       |       |
| MC    | varchar(60) | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

mysql> select * from t;
+-------+------+
| id    | MC   |
+-------+------+
|     1 | MC   |
|     2 | NULL |
|     3 | NULL |
|     4 | NULL |
|     5 | NULL |
|     6 | NULL |
|     7 | NULL |
|     8 | NULL |
|     9 | NULL |
| 10000 | MC   |
+-------+------+
10 rows in set (0.00 sec)

mysql> select * from a;
+------+
| id   |
+------+
| NULL |
|    1 |
|    2 |
+------+
3 rows in set (0.00 sec)

mysql> explain select * from A where id in (select id from T)\G
*************************** 1. row ***************************
           id: 1
  select_type: PRIMARY
        table: A
         type: index
possible_keys: NULL
          key: idx_a
      key_len: 5
          ref: NULL
         rows: 3
        Extra: Using where; Using index
*************************** 2. row ***************************
           id: 2
  select_type: DEPENDENT SUBQUERY
        table: T
         type: unique_subquery
possible_keys: PRIMARY
          key: PRIMARY
      key_len: 4
          ref: func
         rows: 1
        Extra: Using index
2 rows in set (0.02 sec)

unique_subquery是一个索引查找函数,可以完全替换子查询,效率更高。

index_subquery
该联接类型类似于unique_subquery。可以替换IN子查询,但只适合下列形式的子查询中的非唯一索引:
mysql> explain select * from test where id in (select id from a)\G
*************************** 1. row ***************************
           id: 1
  select_type: PRIMARY
        table: test
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 1534755
        Extra: Using where
*************************** 2. row ***************************
           id: 2
  select_type: DEPENDENT SUBQUERY
        table: a
         type: index_subquery
possible_keys: idx_a
          key: idx_a
      key_len: 5
          ref: func
         rows: 1
        Extra: Using index
2 rows in set (0.00 sec)


range
索引范围扫描,只检索给定范围的行,使用一个索引来选择行。key列显示使用了哪个索引。key_len包含所使用索引的最长关键元素。在该类型中ref列为NULL。当使用=、<>、>、>=、<、<=、IS NULL、<=>、BETWEEN或者IN操作符,用常量比较关键字列时,可以使用range:
    mysql> explain select * from t where id=1 or id=10000 or id=3\G;
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: t
         type: range
possible_keys: PRIMARY
          key: PRIMARY
      key_len: 4
          ref: NULL
         rows: 3
        Extra: Using where
1 row in set (0.00 sec)

mysql> explain select * from t where id<=3\G;
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: t
         type: range
possible_keys: PRIMARY
          key: PRIMARY
      key_len: 4
          ref: NULL
         rows: 4
        Extra: Using where
1 row in set (0.00 sec)

ERROR:
No query specified


index
索引全扫描,该联接类型与ALL相同,除了只有索引树被扫描。这通常比ALL快,因为索引文件通常比数据文件小。当查询只使用作为单索引一部分的列时,MySQL可以使用该联接类型。
mysql> explain select * from t\G;
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: t
         type: index
possible_keys: NULL
          key: idx_t_mc
      key_len: 63
          ref: NULL
         rows: 10
        Extra: Using index
1 row in set (0.00 sec)

ERROR:
No query specified


ALL
全表扫描,对于每个来自于先前的表的行组合,进行完整的表扫描。如果表是第一个没标记cnst的表,这通常不好,并且通常在它情况下很差。通常可以增加更多的索引而不要使用ALL,使得行能基于前面的表中的常数值或列值被检索出。

mysql> explain select * from test\G;
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: test
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 1534755
        Extra:
1 row in set (0.06 sec)

ERROR:
No query specified

pssible_keys
pssible_keys列指出MySQL能使用哪个索引在该表中找到行。注意,该列完全独立于EXPLAIN输出所示的表的次序。这意味着在pssible_keys中的某些键实际上不能按生成的表次序使用。如果该列是NULL,则没有相关的索引。在这种情况下,可以通过检查WHERE子句看是否它引用某些列或适合索引的列来提高你的查询性能。如果是这样,创造一个适当的索引并且再次用EXPLAIN检查查询。

为了看清一张表有什么索引,使用SHOW INDEX FROM tbl_name。
mysql> show index from t;
+-------+------------+----------+--------------+-------------+-----------+------
-------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardi
nality | Sub_part | Packed | Null | Index_type | Comment |
+-------+------------+----------+--------------+-------------+-----------+------
-------+----------+--------+------+------------+---------+
| t     |          0 | PRIMARY  |            1 | id          | A         |
     2 |     NULL | NULL   |      | BTREE      |         |
| t     |          1 | idx_t_mc |            1 | MC          | A         |
     2 |     NULL | NULL   | YES  | BTREE      |         |
+-------+------------+----------+--------------+-------------+-----------+------
-------+----------+--------+------+------------+---------+
2 rows in set (0.08 sec)


key
key列显示MySQL实际决定使用的键(索引)。如果没有选择索引,键是NULL。要想强制MySQL使用或忽视pssible_keys列中的索引,在查询中使用FRCE INDEX、USE INDEX或者IGNRE INDEX。对于MyISAM和BDB表,运行ANALYZE TABLE可以帮助优化器选择更好的索引。对于MyISAM表,可以使用myisamchk --analyze。
mysql> explain select * from t where id=1 or mc='1'\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: t
         type: index
possible_keys: PRIMARY,idx_t_mc
          key: idx_t_mc
      key_len: 63
          ref: NULL
         rows: 10
        Extra: Using where; Using index
1 row in set (0.00 sec)

mysql> explain select * from t ignore index(idx_t_mc) where id=1 or mc='1'\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: t
         type: ALL
possible_keys: PRIMARY
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 10
        Extra: Using where
1 row in set (0.00 sec)

key_len
key_len列显示MySQL决定使用的键长度。如果键是NULL,则长度为NULL。注意通过key_len值我们可以确定MySQL将实际使用一个多部关键字的几个部分。

ref
ref列显示使用哪个列或常数与key一起从表中选择行。

rows
rows列显示MySQL认为它执行查询时必须检查的行数。

Extra
该列包含MySQL解决查询的详细信息。下面解释了该列可以显示的不同的文本字符串:

Distinct
MySQL发现第1个匹配行后,停止为当前的行组合搜索更多的行。
Not exists
MySQL能够对查询进行LEFT JIN优化,发现1个匹配LEFT JIN标准的行后,不再为前面的的行组合在该表内检查更多的行。

当使用EXTENDED关键字时,EXPLAIN产生附加信息,可以用SHOW WARNINGS浏览。该信息显示优化器限定SELECT语句中的表和列名,重写并且执行优化规则后SELECT语句是什么样子,并且还可能包括优化过程的其它注解

3.2 优化WHERE子句

MYSQL优化器支持大量的优化工作,详细信息我们需要参看MYSQL联机文档,而且MYSQL优化器每个版本都在进行不断完善。我们的原则就是尽量简化WHERE条件:去除不必要的括号,去除重叠WHERE条件,尽量减少访问的范围等。我们下边给出一个WHERE条件充分利用索引的例子。

和ORACLE等数据库一样,如果我们对where条件后边的字段加上了函数处理的话,将不能利用索引,因此一定要注意把函数处理都要放在后边来处理。
mysql> explain select * from test where id/2<100\G; *************************** 1. row *************************** id: 1 select_type: SIMPLE table: test type: ALL possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 1534755 Extra: Using where 1 row in set (0.78 sec) ERROR: No query specified mysql> explain select * from test where id<100*2\G; *************************** 1. row *************************** id: 1 select_type: SIMPLE table: test type: range possible_keys: idx_test key: idx_test key_len: 4 ref: NULL rows: 16296 Extra: Using where 1 row in set (0.09 sec) ERROR: No query specified

3.3其他优化

MYSQL文档中分别对于join、order by、group by等的优化都做了详细讲述,我们在这里就不给出具体的实例了,大家参考MYSQL联机文档
4 MYSQL高速缓存管理

 

查询缓存存储SELECT查询的sql脚本以及发送给客户端的相应结果。如果随后收到一个相同的查询,服务器从查询缓存中重新得到查询结果,而不再需要解析和执行查询。通过在configure中使用--without-query-cache选项,可以从服务器中彻底去除查询缓存能力。

查询解析之前进行比较,因此下面的两个查询被查询缓存认为是不相同的:


SELECT * FROM tbl_name
Select * from tbl_name


查询必须是完全相同的(逐字节相同)才能够被认为是相同的。另外,同样的查询字符串由于其它原因可能认为是不同的。使用不同的数据库、不同的协议版本或者不同 默认字符集的查询被认为是不同的查询并且分别进行缓存。

如果一个表被更改了,那么使用那个表的所有缓冲查询将不再有效,并且从缓冲区中移出。这包括那些映射到改变了的表的使用MERGE表的查询。一个表可以被许多类型的语句更改,例如INSERT、UPDATE、DELETE、TRUNCATE、ALTER TABLE、DROP TABLE或DROP DATABASE。

查询高速缓存的大小


mysql> SHOW VARIABLES LIKE 'query_cache_size';
+------------------+----------+
| Variable_name    | Value    |
+------------------+----------+
| query_cache_size | 23068672 |
+------------------+----------+
1 row in set (0.01 sec)


修改高速缓存的大小


mysql> SET GLOBAL query_cache_size = 31457280;
Query OK, 0 rows affected (0.00 sec)

mysql> SHOW VARIABLES LIKE 'query_cache_size';
+------------------+----------+
| Variable_name    | Value    |
+------------------+----------+
| query_cache_size | 31457280 |
+------------------+----------+
1 row in set (0.00 sec)

本文作者:
咨询热线:020-85648757 85648755 85648616 0755-27912581 客服:020-85648756 0755-27912581 业务传真:020-32579052
广州市网景网络科技有限公司 Copyright◎2003-2008 Veelink.com. All Rights Reserved.
广州商务地址:广东省广州市黄埔大道中203号(海景园区)海景花园C栋501室
= 深圳商务地址:深圳市宝源路华丰宝源大厦606
研发中心:广东广州市天河软件园海景园区 粤ICP备05103322号 工商注册