《深入浅出MySQL》读书拾遗-优化

  • 在MySQL中,数据库对应操作系统下的数据目录。数据库中的每个表至少对应数据库目录中的一个文件(也可能是多个,这取决于存储引擎)。因此,所使用操作系统的大小写敏感性决定了数据库名和表名的大小写敏感性。
  • 列、索引、存储子程序和触发器名在任何平台上对大小写不敏感。默认情况下,表别名在UNIX中对大小写敏感,但在Windows或Mac OS X中对大小写不敏感。在MySQL中如何在硬盘上保存、使用表名和数据库名由lower_case_tables_name系统变量决定,可以在启动mysqld时设置这个系统变量。
  • MySQL客户端连接成功后,通过show [session|global] status命令可以提供服务器状态信息,也可以在操作系统上使用mysqladmin extended-status命令获得这些消息。
  • “show status like ‘Com_%s’;”可以显示当前session中所有统计参数的值。其中Com_xxx表示每个xxx语句执行的次数,如Com_select(执行select操作的次数,一次查询只累加1)、Com_insert(执行insert操作的次数,对于批量插入的insert操作,只累加一次),还有Com_update/Com_delete/Innodb_rows_read/Innodb_rows_inserted/Innodb_rows_updated/Innodb_rows_deleted等等,通过这些参数可以了解到当前数据库的应用是以插入更新为主还是以查询操作为主,以及各种类型的SQL大致的执行比例是多少。
  • 对于事务型的应用,通过Com_commit和Com_rollback可以了解事务提交和回滚的情况,对于回滚操作非常频繁的数据库,可能意味着应用编写存在问题。
  • Connections(试图连接MySQL服务器的次数),Uptime(服务器工作时间),Slow_queries(慢查询的次数)这三个参数也可以帮助用户了解数据库的基本情况。
  • 通过慢查询日志定位那些执行效率较低的SQL语句,用–log-slow-queries=[file_name]选项启动时,mysqld写一个包含所有执行时间超过long_query_time秒的SQL语句的日志文件。
  • 通过show processlist命令可以查看当前MySQL在进行的线程,包括线程的状态、是否锁表等,可以实时地查看SQL的执行情况,同时对一些锁表操作进行优化。
  • 通过explain分析低效的SQL的执行计划
  • MySQL中索引的存储类型目前只有支持两种,具体和表的存储引擎相关:MyISAM和InnoDB存储引擎都只支持BTREE索引;MEMORY/HEAP存储引擎可以支持HASH和BTREE索引。
  • 查询要使用索引最主要的条件是查询条件需要使用索引关键字,如果是多列索引,那么只有查询条件使用了多列关键字最左边的前缀时,才可以使用索引,否则将不能使用索引。
  • 使用索引
    • 对于创建的多列索引,只要查询条件中用到了最左边的列,索引一般都会被使用。
    • 对于使用like的查询,后面如果是常量并且只有%号不在第一个字符,索引才可能会被使用。
    • 如果对大的文本进行搜索,使用全文索引而不用使用like’%…%’。
    • 如果列名是索引,使用column_name is null将使用索引。
  • 存在索引但不使用索引
    • 如果MySQL估计使用索引比全表扫描更慢,则不使用索引。
    • 如果使用MEMORY/HEAP表并且where条件中不使用”=”进行索引列,那么不会使用索引。heap表只有在”=”的条件下才会使用索引。
    • 用or割开的条件,如果or前的条件中的列有索引,而后面的列没有索引,那么涉及的索引都不会被使用。
    • 如果不是索引列的第一部分。
    • 如果like是以%开始。
    • 如果列类型是字符串,那么一定记得在where条件中把字符常量值用引号引起来,否则的话即使这个列上有索引,MySQL也不会用到。
  • 如果索引現在工作,Handler_read_key的值将很高,这个值代表了一个行被索引值读的次数,很低的值表明增加索引得到的性能改善不高,因为索引并不经常使用。
  • Handler_read_rnd_next的值高则意味着查询运行低效,并且应该建立索引补救。这个值含义是在数据文件中读一下行的请求数。如果現在进行大量的表扫描,Handler_read_rnd_next的值较高,则通常说明表索引不正确或写入的查询没有利用索引。
  • 当从一个文本文件装载一个表时,使用LOAD DATA INFILE。这通常从使用很多INSERT语句快20倍。
  • 默认情况下,MySQL对所有GROUP BY col1, col2…的字段进行排序。这与在查询中指定ORDER BY col1, col2…类似。如果查询包括GROUP BY但想要避免排序結果的消耗,则可以指定ORDER BY NULL禁止排序。
  • 对于含有OR的查询子句,如果要利用索引,则OR之间的每个条件列都必须用到索引:如果没有索引,则应该考虑增加索引。
  • 可以通过查询Table_locks_waited和Table_locks_immediate状态变量来分析系统上的表锁定争夺,如果Table_locks_waited的值比较高,则说明存在着较严重的表级锁争用情况。
  • MyISAM存储引擎有一个系统变量concurrent_insert,专门用以控制其并发插入的行为,其值分别可以为0(不允许并发插入)、1(MyISAM表中没有空洞,可允许一个进程在读,另一个进程在尾插入),2(无论有没有空洞,都可以在表尾插入)。
  • 如果一个进程请求某个MyISAM表的读锁,同时另一个进程也请求同一表的写锁,MySQL会让写进程先获得锁,这是因为MySQL认为写请求一般比读请求重要,这也是MyISAM表不太适合于有大量更新操作和查询操作应用的原因,因为,大量的更新操作会造成查询操作很难获得读锁,从而可能永远阻塞。
  • MySQL服务启动后,我们可以用”show variables”和”show status”命令查看MySQL的服务器静态参数值和动态运行状态信息。其中前者是在数据库启动后不会动态更改的值,比如缓冲区大小、字符集、数据文件名称等;后者是数据库运行期間的动态变化的信息,比如锁等待、当前连接数等;也可以在操作系统下直接查看数据库参数或数据库状态信息,”mysqladmin -uroot variables”。
  • 一些影响MySQL性能的重要参数:
    • key_buffer_size:设置索引块缓存的大小,它被所有线路共享,此参数只适用于MyISAM存储引擎。
    • table_cache:表示数据库用户打开表的缓存数量。每个连接进来,都会至少打开一个表缓存。因此,table_cache与max_connections有关,对于M个并行运行的连接,应该让表缓存至少有M*N,N为可以执行的查询的一个联接中表的最大数量。
    • innodb_buffer_pool_size:定义了InnoDB存储引擎的表数据和索引数据的最大内存缓冲区大小。和MyISAM存储引擎不同,MyISAM的key_buffer_size只缓存索引键,而innodb_buffer_pool_size却是同时为数据块和索引块做缓存。这个值设得越高,访问表中数据需要的磁盘I/O就越少。
    • innodb_flush_log_at_trx_commit:用来控制缓冲区中的数据写入到日志文件以及日志文件数据刷新到磁盘的操作时机。
    • innodb_additional_mem_pool_size:表示InnoDB存储引擎用来存储数据库结构和其他内部数据结构的内存池大小,其默认值是1MB。应用程序里的表越多,则需要在这里分配越多的内存。
    • innodb_support_xa:设置是否支持分布式事务,默认值是ON或者1,表示支持分布式事务。
    • innodb_log_buffer_size:表示日志缓存的大小。如果它的值设置太高了,可能会浪费内存,因为它每秒都会刷新一次,因此无须设置超过1秒所需的内存空间。默认值为1MB。
    • innodb_log_file_size:表示一个日志组(log group)中每个日志文件的大小。此参数在高写入负载尤其是大数据集的情况下很重要。这个值越大则性能相对越高,但是带来的副作用是,当系统灾难时恢复时间会加大。系统默认值为5MB。
This entry was posted in MySQL. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>