1.MySQL如何打开和关闭表
当执行mysqladmin status命令,可以查看类似下面的信息:
Uptime: 426 Running threads: 1 Questions: 11082
Reloads: 1 Open tables: 12
该Open tables值为12如果只有6个表就有点令人费解的。
MySQL是多线程,所以在同一时间有很多客户查询一个指定表。为减少这个问题用多个客户端会话在相同表上有不同状态,该表由每个并发会话独立打开。但通常会使用额外的内存增加性能开销。MyISAM表,一个额外的文件描述符需要对具有该表公开的每个客户端的数据文件。(通过对比,索引文件描述符之间的所有会话共享)。
table_open_cache和max_connections系统变量影响最大的一些文件服务器保持开放。如果你增加一个或两个值,可能会碰到的操作系统在每个打开的文件描述符的进程数限制。许多操作系统允许增加打开文件的限制,虽然该方法从系统到系统的广泛的变化。咨询操作系统文档以确定是否可以增加限制和如何做。
table_open_cache与max_connections有关。例如,200连接并行运行,制定一个表内存值最少200 * N,其中n是最大数量的表每参加任何查询执行。还必须为临时表和文件保留一些额外的文件描述符。
确保操作系统可以处理打开的文件描述符的隐含的数table_open_cache设置。如果table_open_cache设置太高,MySQL可能运行的文件描述符和拒绝连接,无法执行查询,很不可靠。必须考虑到MyISAM存储引擎需要为每一个独特的打开表两个文件描述符。可以增加可用文件描述符使用--open-files-limit 启动选项。
打开表缓存保持在一个水平的table_open_cache的条目。默认值时400;可以使用mysqld的 --table_open_cache选项来改变。注意MySQL可能比执行该查询临时的打开更多表。
MySQL在下面的情况关闭未使用的表和从表缓存删除它:
-
当缓存满了一个线程试图打开不在高速缓存中的一个表。
-
当缓存中包含多table_open_cache条目和一个表缓存中没有再由任何线程使用。
-
当一个表刷新操作时。这发生在当某人执行FLUSH TABLES命令或执行mysqladmin flush-tables或mysqladmin refresh 命令。
当表缓存填充,服务器使用下列程序找到一个缓存条目使用:
-
释放目前不在使用中的表,从表最近最少使用释放。
-
如果需要打开一个新表,但是内存被用满而且没有表可以被释放,则内存需要临时扩展。当缓存是一个临时的扩展状态和表从一个以前未使用的状态,该表关闭并从缓存中释放。
MyISAM表打开每一个并行连接。这意味着表需要打开两次如果两个线程访问同一个表或如果一个线程访问表两次相同的查询(通过加入表本身)。每个并发打开需要在表缓存条目。任何MyISAM表先打开需要两个文件描述符:一个数据文件和一个索引文件。表中的每一个额外的使用只有一个文件描述符的数据文件。索引文件描述符之间的所有线程共享。
如果使用HANDLER tbl_name OPEN命令打开表,一个专用的表对象分配给线程。此表的对象不被其他线程共享和不关闭直到线程调用HANDLER tbl_name CLOSE 或线程终止。当这一切发生的时候,表放回表的高速缓存(如果缓存没满)。
你可以决定你的表缓存太小,通过检查mysqld状态变量opened_tables,这表明表打开操作的数量自服务器启动:
mysql> SHOW GLOBAL STATUS LIKE 'Opened_tables';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Opened_tables | 2741 |
+---------------+-------+
如果值是非常大或迅速增加,即使你没有发出许多FLUSH TABLES语句,增加高速缓存的大小。
2.MySQL如何使用内部临时表(How MySQL Uses Internal Temporary Tables)
在某些情况下,服务器创建内部临时表而处理查询。这样的表可以保留在内存和存储引擎MEMORY处理,或存储在磁盘上的存储引擎MyISAM处理。服务器可能会创建一个临时表最初是作为一个内存中的表,然后如果它变得太大将它转换为一个磁盘上的表。用户没有直接权限控制当服务器创建一个内部临时表或存储引擎服务器使用管理。
临时表可以在如下条件下产生的:
-
如果是 ORDER BY子句和一个不同的GROUP BY子句,或者是ORDER BY 或 GROUP BY 的列join 序列,一个临时表将创建。
-
DISTINCT结合ORDER BY 可能需要一个临时表。
-
如果使用SQL_SMALL_RESULT选项,MySQL使用一个在内存中的临时表,除非查询也包含元素(后来所描述的)需要对磁盘存储。
-
驱动表(在FROM子句的子查询)。
-
在子查询或半连接的物化创建的表。
确定查询是否需要一个临时表,使用EXPLAIN并且检查额外列看它是否Using temporary。EXPLAIN 将不是必要 Using temporary 驱动或物化的临时表。
某些情况下防止内存中的临时表的使用,在这种情况下,服务器使用一个磁盘上的表,而不是:
-
在表中有BLOB 或 TEXT列存在。
-
有任何GROUP BY 或 DISTINCT子句超过512字节存在。
-
在选择列表中的列存在任何大于512字节,如果使用UNION 或UNION ALL
如果内部临时表太大,MySQL将把它会移动到磁盘上。内存临时表的最大值是tmp_table_size的最小值和max_heap_table_size的值。这不同于内存表明确由CREATE TABLE创建:这样的表,max_heap_table_size系统变量允许大表增长并不移动到磁盘。
当服务创建内部临时表(无论是在内存或磁盘上),它增加Created_tmp_tables系统变量。如果服务创建内部临时表在磁盘上(无论初始或转换在内存表),它将增加Created_tmp_disk_tables系统变量。
阅读(185) | 评论(0) | 转发(0) |