每个并行访问都打开一个表。这意味着当有两个线程同时访问一个表,或者一个线程在同一个查询中访问两次这个表(例如,在表连接中连接自己),那么这个表就需要被打开两次。每次并发的打开都在表缓存中请求一个表目。每个表第一次打开时都需要两个文件描述符:一个给数据文件,一个给索引文件。其他新增的对该表的打开则只需要一个文件,给数据文件。索引文件的描述符在所有的线程间是共享的。
如果使用 HANDLER tbl_name OPEN 语句打开表,则有一个专用的表对象给该线程。这个表对象不和其他线程共享,并且除非调用 HANDLER tbl_name CLOSE 语句或者线程结束,否则它不会关闭;这样的话,它就重新放回表索引中(如果索引还未满)。详情请看"14.1.3 HANDLER Syntax"。
可以检查mysqld 的状态变量 Opened_tables 来判断表索引是否太小了:
mysql> SHOW STATUS LIKE 'Opened_tables'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | Opened_tables | 2741 | +---------------+-------+ |
如果这个值比较大,不过完全没必要执行一大堆的 FLUSH
TABLES 语句。只需加大表索引缓存大小即可。
在一些数据库中创建太多表的缺点
如果在一个目录下有很多的 MyISAM 或 ISAM 表,打开,关闭,创建等操作就会变慢。如果在很多不同的表上执行SELECT 语句,当表缓存满了之后这就会有些开销,因为每个表都需要被打开,其他的必须关闭。可以加大表缓存来降低这个开销。

