Mysql优化

做一件事,一般遵循几个原则:为什么做,怎么做,要达到什么目标。

之所以要进行SQl优化,是因为在现有的硬软件资源下,数据库的性能表现未能达到预期。

故要做到在当前硬软件资源不变的情况下,大幅度提高数据库性能,以达到或超出我们的预期。

数据库级别的优化:

是否具有适当的表结构

是否在合适的地主加上了下压角的索引

表是否使用了正确遥存储引擎

是否为表进行了适当的行格式化(如行压缩)

是否使用了正确的锁策略

是否进行了正确的数据缓存

硬件级别的优化:

如果是IO瓶颈,则分布到多块硬盘并行读写。

如果是CPU瓶颈,就需要考虑到集群。

最常用的还是SQL语句优化:

  SELECT 语句的优化:

1首先检查是否加了索引。

2d在SELECT中是否使用了耗时函数,需尽量避免

3尤其是大表,尽量避免全表扫描

4更新表的统计信息,使优化器能生成有效的执行计划

5 尽量使SQl趋向于优化器,便于其理解

6对于一个复杂SQL,无法直接使用上述方法,则可通过EXPLAIN 分析其执行计划,然后不断调节

(When you reach a certain level of expertise, reading the EXPLAIN plan might be your first step for every query.)

7调节Mysql用于缓存的内存区域大小及属性,充分利用InnoDB buffer pool  和MyISAM key cache,及Mysql query cache,对于重复Query可更快执行

8 处理好锁问题。

为了减少空间占用,还要考虑表设计环节:选用哪种数据类型,数据大小如何,是否指定row_format??

对于已存在的表进行结构优化,如何评估,可使用  PROCEDURE ANALYSE(ROW_COUNT,DATA_MEMORY)

详情也可参见:

9.4.2.4 Using PROCEDURE ANALYSE

重要一步:修改 innodb_buffer_pool_size的大小,默认为128M。

9.8 Understanding the Query Execution Plan

优化Mysql,诊断Mysql问题所在,才能对证下药。而query execution plan 就是诊断Mysql的终极利刃。

在优化Mysql表时,如果修改了表结构,则别忘了更新表统计信息,ANALYZE TABLE .

9.8.5 Estimating Query Performance

也可以人工估计查询性能。影响性能的主要是磁盘查找(disk seek)次数。如果能粗略估算出 disk seek数,测可大致知道该SQl的性能。

 For bigger tables, you can estimate that, using B-tree indexes, you need this many seeks to find a row: log(row_count) / log(index_block_length / 3 * 2 / (index_length + data_pointer_length)) + 1.

如 mysql 中,index_block_length==1024,data_pointer_length==4;

For a 500,000-row table with a key value length of three bytes (the size of MEDIUMINT), the formula indicateslog(500,000)/log(1024/3*2/(3+4)) + 1 = 4 seeks.

This index would require storage of about 500,000 * 7 * 3/2 = 5.2MB (assuming a typical index buffer fill ratio of 2/3), so you probably have much of the index in memory and so need only one or two calls to read data to find the row.

For writes, however, you need four seek requests to find where to place a new index value and normally two seeks to update the index and write the row.

query cache(查询缓存)

将查询语句作为Key,结果作为Value,缓存起来。同样的查询直接从缓存中取。缓存结果有过期策略,所以query cache 不宜过大【过大,会增加其维护的成本】;一般query cache in 1M~100M之间。

有两个系统变量,可控制query cache:query_cache_size和query_cache_type.

query_cache_size,控制可用缓存大小,query_cache_type,决定是否起用缓存。

[To set the size of the query cache, set the query_cache_size system variable. Setting it to 0 disables the query cache, as does setting query_cache_type=0. By default, the query cache is disabled. This is achieved using a default size of 1M, with a default for query_cache_type of 0.]

9.11 Optimizing Locking Operations

锁是Mysql在并发时管理数据的机制。Mysql共有两类锁:由MysqlServer自行处理,不对外交互的,称内锁[Internal Locking];与程序一起管理的,称为外锁[External Locking]

内锁有:行锁[Row-Level Locking],用于INNODB,MySQL uses row-level locking for InnoDB tables to support simultaneous write access by multiple sessions, making them suitable for multi-user, highly concurrent, and OLTP applications.

 

表锁[Table-Level Locking],用于MyISAM,MEMORY,MERGE表,在同一时间,只允许一个用户[session]更新数据。

This locking level makes these storage engines more suitable for read-only, read-mostly, or single-user applications.

Mysql授权锁的方式如下

授权写锁,如果当前数据上没有锁,则授予;否则,将申请放入写锁队列。

授权读锁,如果当前数据上没有锁,则授予;否则,将申请放入读锁队列。

如果队列中同时有写锁与读锁,则Mysq优先处理写锁;以防读出错误数据。

原文地址:https://www.cnblogs.com/itdev/p/5847189.html