您的位置:首页 > 数据库

数据库优化笔记1

2012-09-16 15:44 176 查看
show status 显示当前mysql数据库的状态,会列出很多列表条。专注 com 开头的指令

比如 Com_select 记录着总共执行了多少次 select

通常可以这样做

show status like 'Com%'; 列出所有com开头的指令

在执行命令前添加额外的指令结果也会不一样 比如

show status session like 'Com_select'; 当前控制台的 (也就是连接数据库到目前)

show global stats like 'Com_select'; 所有的

show gobal status like 'Connections'; 发怒i连接数据库服务器的次数

show global status like 'uptime'; 查看数据库总启动时间

show global status like 'slow_queries'; 查看慢查询(默认是10秒)可以自己设定

show variables like 'long_query_time'; 这个就返回 定义的符合慢查询的时间。 返回为 10

// 设置慢查询描述 (只要大于1秒钟就会被记录,但需要开启慢查询日志)

set long_query_time = 1;

开始优化测试

数据量 580W条 testid 为数据id (未加主键索引)

select * from test where testid = 1234567


1 row in set (2.11 sec)1 row in set (2.11 sec)1 row in set (2.11 sec)

使用2秒钟的时间,(为了测试慢查询,故意没给test表加主键索引)

但是如果没有设定慢查询日志,管理员很难知道 到底那里的那条sql指令导致了慢查询 ,因此我们需要记录慢查询日志

【开始配置慢查询日志】

数据库版本:5.0 ( 5.5 的查看指令结果可能和他不太一样,目前我用的是5.0 就根据5.0的来配置)

1:查看大于多少秒算是慢查询

show variables like 'long%';








显示为 10秒

2:重设慢查询时间 设为1秒

set long_query_time = 1;


【注意】

如果是在本次连接中 通过修改变量 long_query_time 的值的方式将慢查询时间设为1 那么只有在本次会话中才会是1秒,断开后重新连接数据库还会变成默认的10秒

如果想一直保持1秒 则可以编辑 my.ini 添加一下配置

long_query_time=1

附加:

log-queries-not-using-indexes=on 记录无索引查询到日志

3:查看是否开启慢查询日志

show variables like '%slow%';




log_slow_queries 为 Off 则说明未开启

在 my.ini中添加一下配置

log-slow-queries=master-0-slow.log

再次查看

show variables like '%slow%';




结果为 ON 表示已开启。

设置完毕之后 可以在 mysql date目录下看到 master-0-slow-log 文件,该文件会记录所有的慢查询

4:来执行一条查询指令

select * from test where testid=1234567




查询一条记录i 花费了 3秒中的时间。 打开慢查询日志文件 能够看到如下信息

# Time: 120916 17:48:51
# 在 12年9月16日
# User@Host: root[root] @ localhost [1
#27.0.0.1]
# 用户 root 在本地
# Query_time: 4  Lock_time: 0  Rows_s
ent: 1  Rows_examined: 5800000
# 执行指令时间花费4秒,没有锁表,返回1行,查询了580W条记录
#具体指令如下
use test;
select * from test where testid = 1234567;


当然如果想解决上述的查询速度,那么只要给 testid 加上主键就可以了。 只不过这里是为了测试 所以就先不解决了。

如果在不清楚 该查询 那点出了问题 导致变成慢查询 可以使用 explain 来分析

explain select * from test where testid = 1234567




【select_type 查询类型】

simple :简单的 seect (没有使用 union 或子查询)

primary :最外层的 select

union : 第二层,在select之后使用了 union

depedent union : union 语句中的第二个 select , 依赖于外部子查询

subquery : 子查询中的第一个 select

dependent subquery : 子查询中的第一个 subquery 依赖于外部的子查询

derived : 派生表 select(from自居中的子查询)

【type 表示连接类型】

ALL --> 说明该查询会对全表扫描

system --> 表仅有一行 (不太清楚)

const : 表最多有一行匹配

eq_ref :最好的连接类型

等等 其他的类型,具体是什么 后期在 explain 笔记中会详细描述

【possible_keys 可能会用到的索引,但在实际查询中就算他额值不是null 也可能不会用到这里预估的索引】

【key 实际上要用的索引】

如果在查询中看到 这2个结果 都为 null 则说明 本次查询并没有使用索引,可以在where 子句中分析 并给合适的列添加索引来提高速度

【key_len 显示使用索引的长度】

在联合索引中 该字段的结果能够知道 mysql 真正使用的索引。

换句话说 有些时候我们可能会给2个列添加联合索引,但实际查询中可能只会使用其中的一个索引,看他就知道到底用了那个索引。

【ref 那些字段或常量被用来和key配合从表 汇总查询记录出来】

【rows 显示总送查询了多少条记录】

【extra】

using filesort : 当query中包含 order by 操作,而且无法利用索引完成排序

案例:

test 表没有索引,但是使用了排序

select * from test order by testid desc;

在这个时候因没有索引 他会用文件来排序,反正这样做的话性能会很差,如果看到这种结果就很惨

using where :不用读取表中所有信息,仅通过索引就可以获取所需的数据(尽量要看到这种结果)

using temporary :不清楚啥意思,没有案例可以分析。

总结:速度慢理由 是因为 testid没有索引 根据下面的分析

1:慢查询日志看到 select * from test where testid = 1234567 是个慢查询

2:explain 结果发现 type 为 ALL 并且 possible_key 为 null 以及 key 也是null 证明么有用到索引,在加上rows 返回的是 表的总记录条数

仅仅查询一个 id 为指定的记录 搜索了全表 通常理由就是因为 该查询没有用到索引,所以给 testid加主键即可解决问题。

【常见的sql优化手段】

1:使用 order by null 禁用排序

在使用 group by 语句时 他默认会有排序的操作,通过下面的指令

explain select * from test group by testid\G

能看到

【Extra】

using filesort

是对文件进行排序,这里我们可以进行小优化 比如

explain select * from test group by tsetid order by null

这样可以组织他的文件排序 using filesort

2:尽量使用表连接 (join)少用子查询,因为 join 在查询时不会创建临时表。

3:精度要求高的应用,(如存储金额之类的表)尽量不要使用浮点型,因为容易失精度,建议使用定点数(decimal) 来存储数据

create tble test(m float(10,2));

insert into test m value(100000.55); 结果进入的却是 100000.54

create table test(m decimal(10,2));

insert into test m value(100000,55); 正确!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: