• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • 针对多个表进行优化

    保持单个查询快速的某些技术涉及在多个表之间拆分数据。当表的数量达到数千甚至几百万时,处理所有这些表的开销将成为新的性能考虑因素。

    MySQL如何打开和关闭表

    当执行mysqladmin status命令时,应该看到类似以下的内容:

    Uptime: 426 Running threads: 1 Questions: 11082
    Reloads: 1 Open tables: 12
    

    Open tables如果表少于12个,则12 的值可能会令人困惑。

    MySQL是多线程的,因此可能有许多客户端同时为给定表发出查询。为了最大程度地减少同一张表上具有不同状态的多个客户端会话的问题,每个并发会话会独立打开该表。这会使用额外的内存,但通常会提高性能。对于MyISAM表,每个打开表的客户端的数据文件都需要一个额外的文件描述符。(相比之下,索引文件描述符在所有会话之间共享。)

    table_open_cachemax_connections系统变量影响服务器保持打开的文件的最大数量。如果增加这两个值中的一个或两个,则可能会遇到操作系统对打开文件描述符的每个进程数施加的限制。许多方法允许您增加打开文件的限制,尽管方法因系统而异。请查阅您的操作系统文档,以确定是否可以增加限制以及如何增加限制。

    table_open_cache与有关max_connections。例如,对于200个并发运行的连接,指定的表缓存大小至少为,其中是您执行的任何查询中每个联接的最大表数。您还必须为临时表和文件保留一些额外的文件描述符。200 *NN

    确保您的操作系统可以处理该table_open_cache设置所隐含的打开文件描述符的数量。如果table_open_cache设置得太高,MySQL可能会用尽文件描述符,并表现出诸如拒绝连接或无法执行查询之类的症状。

    还应考虑到MyISAM存储引擎对于每个唯一的打开表都需要两个文件描述符。要增加可用于MySQL的文件描述符的数量,请设置open_files_limit系统变量。请参见第B.4.2.17节“找不到文件和类似错误”。

    打开表的缓存保持在table_open_cache条目级别。服务器在启动时自动调整缓存大小。要显式设置大小,请table_open_cache在启动时设置系统变量。MySQL可能会临时打开更多表来执行查询,如本节后面所述。

    在以下情况下,MySQL关闭未使用的表并将其从表缓存中删除:

    • 当缓存已满并且线程尝试打开不在缓存中的表时。
    • 当高速缓存包含多个table_open_cache条目并且高速缓存中的表不再被任何线程使用时。
    • 当进行表刷新操作时。当有人发出一条FLUSH TABLES语句或执行mysqladmin flush-tablesmysqladmin refresh命令时,会发生这种情况。

    当表高速缓存填满时,服务器将使用以下过程找到要使用的高速缓存条目:

    • 从最近最少使用的表开始,释放当前未使用的表。
    • 如果必须打开一个新表,但是缓存已满并且无法释放任何表,则可以根据需要临时扩展缓存。当缓存处于临时扩展状态并且表从已使用状态变为未使用状态时,该表将关闭并从缓存中释放。

    MyISAM将为每个并发访问打开一个表。这意味着,如果两个线程访问同一个表,或者如果一个线程在同一查询中两次访问该表(例如,通过将表连接到自身),则该表需要打开两次。每个并发打开都需要在表缓存中有一个条目。任何MyISAM表的第一次打开都需要两个文件描述符:一个用于数据文件,一个用于索引文件。该表的每次其他使用都只为数据文件使用一个文件描述符。索引文件描述符在所有线程之间共享。

    如果要使用该语句打开表,则会为该线程分配专用的表对象。该表对象不与其他线程共享,并且在线程调用或线程终止之前不会关闭。发生这种情况时,会将表放回表高速缓存中(如果高速缓存未满)。请参见“ HANDLER语句”。HANDLER tbl_name OPENHANDLER tbl_name CLOSE

    要确定表缓存是否太小,请检查Opened_tables状态变量,该变量指示自服务器启动以来表打开操作的数量:

    mysql> SHOW GLOBAL STATUS LIKE 'Opened_tables';
    +---------------	+-------	+
    | Variable_name 	| Value 	|
    +---------------	+-------	+
    | Opened_tables 	| 2741  	|
    +---------------	+-------	+
    

    如果该值很大或迅速增加,即使您没有发出很多FLUSH TABLES语句,也请table_open_cache在服务器启动时增加该值。


    在同一数据库中创建多个表的缺点

    如果MyISAM同一数据库目录中有许多表,则打开,关闭和创建操作的速度很慢。如果SELECT在许多不同的表上执行语句,则表高速缓存已满时会产生一些开销,因为对于必须打开的每个表,都必须关闭另一个表。您可以通过增加表缓存中允许的条目数来减少此开销。