Tag Archive for 'MySQL'

Page 2 of 5

MySQL性能优化15 – MyISAM 存储引擎

对于 MyISAM 类型的表,可以通过以下方式快速的导入大量的数据。

loading the data

这两个命令用来打开或者关闭 MyISAM 表非唯一索引的更新。在导入大量的数据到一个非空的 MyISAM 表时,通过设置这两个命令,可以提高导入的效率。对于导入大量数据到一个空的 MyISAM 表,默认就是先导入数据然后才创建索引的,所以不用进行设置。

MySQL性能优化14 – HIGH_PRIORITY/LOW_PRIORITY/INSERT DELAYED

MySQL 还允许改变语句调度的优先级,它可以使来自多个客户端的查询更好地协作,这样单个客户端就不会由于锁定而等待很长时间。改变优先级还可以确保特定类型的查询被处理得更快。

我们首先应该确定应用的类型,判断应用是以查询为主还是以更新为主的,是确保查询效率还是确保更新的效率,决定是查询优先还是更新优先。

下面我们提到的改变调度策略的方法主要是针对 MyISAM 存储引擎的,对于 InnoDB 存储引擎,语句的执行是由获得行锁的顺序决定的。

MySQL 的默认的调度策略可用总结如下:

  • 写入操作优先于读取操作。
  • 对某张数据表的写入操作某一时刻只能发生一次,写入请求按照它们到达的次序来处理。
  • 对某张数据表的多个读取操作可以同时地进行。

MySQL 提供了几个语句调节符,允许你修改它的调度策略:

如果写入操作是一个 LOW_PRIORITY(低优先级)请求,那么系统就不会认为它的优先级高于读取操作。在这种情况下,如果写入者在等待的时候,第二个读取者到达了,那么就允许第二个读取者插到写入者之前。只有在没有其它的读取者的时候,才允许写入者开始操作。这种调度修改可能存在 LOW_PRIORITY 写入操作永远被阻塞的情况。

SELECT 查询的 HIGH_PRIORITY (高优先级)关键字也类似。它允许 SELECT插入正在等待的写入操作之前,即使在正常情况下写入操作的优先级更高。另外一种影响是,高优先级的 SELECT 在正常的 SELECT语句之前执行,因为这些语句会被写入操作阻塞。

如果你希望所有支持 LOW_PRIORITY选项的语句都默认地按照低优先级来处理,那么请使用 --low-priority-updates 选项来启动服务器。通过使用 INSERT HIGH_PRIORITY 来把 INSERT[/cci] 语句提高到正常的写入优先级,可以消除该选项对单个 INSERT 语句的影响。

MySQL性能优化13 – SQL_NO_CACHE/SQL_CACHE

可以在 SELECT 语句中指定查询缓存的选项,对于那些肯定要实时的从表中获取数据的查询,或者对于那些一天只执行一次的查询,我们都可以指定不进行查询缓存,使用 SQL_NO_CACHE 选项。

对于那些变化不频繁的表,查询操作很固定,我们可以将该查询操作缓存起来,这样每次执行的时候不实际访问表和执行查询,只是从缓存获得结果,可以有效地改善查询的性能,使用 SQL_CACHE 选项。

下面是使用 SQL_NO_CACHESQL_CACHE 的例子:

1
2
mysql> select sql_no_cache id,name from test3 where id < 2;
mysql> select sql_cache id,name from test3 where id < 2;

注意:查询缓存的使用还需要配合相应得服务器参数的设置,相关情况请参考服务器优化的章节。

MySQL性能优化12 – FORCE INDEX/IGNORE INDEX

FORCE INDEX 通常用来对查询强制使用一个或者多个索引。 MySQL 通常会根据统计信息选择正确的索引,但是当查询优化器选择了错误的索引或者根本没有使用索引的时候,这个提示将非常有用。

IGNORE INDEX 提示会禁止查询优化器使用指定的索引。在具有多个索引的查询时,可以用来指定不需要优化器使用的那个索引,还可以在删除不必要的索引之前在查询中禁止使用该索引。 Continue reading ‘MySQL性能优化12 – FORCE INDEX/IGNORE INDEX’

MySQL性能优化11 – 使用 Hint

很多数据库都提供了 Hint (提示)的概念,使用 Hint 可以在数据库为 SQL 产生执行计划的时候提供额外的信息,从而使 SQL 按照我们预定的执行计划执行。 Hint 的使用并不是必须的,大部分情况下,都不需要使用 Hint 来影响执行计划,只有在少数情况下,我们才需要使用。下面我们介绍的是 MySQL 中使用的比较多的几个 Hint 。(待续)

MySQL性能优化10 – OPTIMIZE

OPTIMIZE TABLE 是指对表进行优化。如果已经删除了表的一大部分数据,或者如果已经对含有可变长度行的表(含有 VARCHAR 、 BLOB 或 TEXT 列的表)进行了很多更改,就应该使用 OPTIMIZE TABLE命令来进行表优化。这个命令可以将表中的空间碎片进行合并,并且可以消除由于删除或者更新造成的空间浪费。 OPTIMIZE TABLE 命令只对 MyISAM 、 BDB 和 InnoDB 表起作用。表优化的工作可以每周或者每月定期执行,对提高表的访问效率有一定的好处,但是需要注意的是,优化表期间会锁定表,所以一定要安排在空闲时段进行。 Continue reading ‘MySQL性能优化10 – OPTIMIZE’

MySQL性能优化9 – ANALYZE 和 CHECK

ANALYZE TABLE 和 CHECK TABLE 分别用来进行表分析和表检查。表分析主要用来获得关键字的分布情况,对执行计划的产生有帮助,而表检查主要用来检查表或者视图是否存在错误。

ANALYZE TABLE 用来分析和存储表的关键字的分布,使得系统获得准确的统计信息,影响 SQL 的执行计划的生成。对于数据基本没有发生变化的表,是不需要经常进行表分析的。但是如果表的数据量变化很明显,用户感觉实际的执行计划和预期的执行计划不同的时候,执行一次表分析可能有助于产生预期的执行计划。 Continue reading ‘MySQL性能优化9 – ANALYZE 和 CHECK’

MySQL性能优化8 – 索引工作情况

如果索引正在工作, Handler_read_key 的值将很高,这个值代表了一个行被索引值读的次数,很低的值表明增加索引得到的性能改善不高,因为索引并不经常使用。

Handler_read_rnd_next 的 值高则意味着查询运行低效,并且应该建立索引补救。这个值的含义是在数据文件中读下一行的请求数。如果正进行大量的表扫描, Handler_read_rnd_next 的 值较高,则通常说明表索引不正确或写入的查询没有利用索引,具体如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
mysql> show status like 'Handler_read%';

+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| Handler_read_first | 0 |
| Handler_read_key | 5 |
| Handler_read_next | 0 |
| Handler_read_prev | 0 |
| Handler_read_rnd | 0 |
| Handler_read_rnd_next | 2055 |
+-----------------------+-------+

6 rows in set (0.00 sec)

从上面的例子中可以看出,目前使用的 MySQL 数据库的索引情况并不理想。

MySQL性能优化7 – 索引选择性

索引的 “ 选择性 ” 是指在该索引列里存储不同值的数目和记录数的比。比如某个表的记录数是 1000 条,而该表的索引列的值只有 900 个不同的值(有 100 个是相同或是空)。这样索引的可选择性为 900/1000 为 0.9 。这样当然效果就不好,最好的索引可选择性(如主键索引)是 1.0 。索引的可选择性是衡量索引的利用率的方法,比如在极端的情况下,一个表记录数是 1000 ,而索引列的值只有 10 个不同的值,则索引的可选择性很差(只有 0.01 )。这样的情形使用全表扫描要比采用索引还好。 Continue reading ‘MySQL性能优化7 – 索引选择性’

MySQL性能优化6 – 索引类型

MyISAM 存储引擎的 表的数据和索引是自动分开存储的,各自是独立的一个文件; InnoDB 存储引擎 的表的数据和索引是存储在同一个表空间里面,但可以有多个文件组成。

MySQL 中索引的存储类型目前只有两种( btree 和 hash ),具体和表的存储引擎相关: MyISAM 和 InnoDB 存储引擎都只支持 btree 索引; MEMORY/HEAP 存储引擎可以支持 hash 和 btree 索引。

MEMORY 存储引擎的表可以选择使用 BTREE 索引或者 HASH 索引,两种不同类型的索引各有其不同的适用范围。 HASH 索引有一些重要的特征需要在使用的时候特别注意,如下所示。 Continue reading ‘MySQL性能优化6 – 索引类型’