MySQL定期分析检查与优化表的方法小结

定期分析表

ANALYZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name [, tbl_name]

本语句用于分析和存储表的关键字分布。在分析期间,使用一个读取锁定对表进行锁定。这对于MyISAM, BDB和InnoDB表有作用。对于MyISAM表,本语句与使用myisamchk -a相当。

MySQL使用已存储的关键字分布来决定,当您对除常数以外的对象执行联合时,表按什么顺序进行联合。

mysql> analyze table a;
+--------+---------+----------+-----------------------------+
| Table  | Op      | Msg_type | Msg_text                    |
+--------+---------+----------+-----------------------------+
| test.a | analyze | status   | Table is already up to date |
+--------+---------+----------+-----------------------------+
1 row in set (0.00 sec)

定期检查表

CHECK TABLE tbl_name [, tbl_name]  [option]

option = {QUICK | FAST | MEDIUM | EXTENDED | CHANGED}
检查一个或多个表是否有错误。CHECK TABLE对MyISAM和InnoDB表有作用。对于MyISAM表,关键字统计数据被更新。

mysql> check table a;
+--------+-------+----------+----------+
| Table  | Op    | Msg_type | Msg_text |
+--------+-------+----------+----------+
| test.a | check | status   | OK       |
+--------+-------+----------+----------+
1 row in set (0.00 sec)
CHECK TABLE也可以检查视图是否有错误,比如在视图定义中被引用的表已不存在。
我们为上面的表a创建一个视图

mysql> create view a_view as select * from a;
Query OK, 0 rows affected (0.02 sec)

然后CHECK一下该视图,发现没有问题

mysql> check table a_view;
+-------------+-------+----------+----------+
| Table       | Op    | Msg_type | Msg_text |
+-------------+-------+----------+----------+
| test.a_view | check | status   | OK       |
+-------------+-------+----------+----------+
1 row in set (0.00 sec)
现在删掉视图依赖的表

mysql> drop table a;
Query OK, 0 rows affected (0.01 sec)
再CHECK一下刚才的视图,发现报错了

mysql> check table a_view\G;
*************************** 1. row ***************************
   Table: test.a_view
      Op: check
Msg_type: Error
Msg_text: Table 'test.a' doesn't exist
*************************** 2. row ***************************
   Table: test.a_view
      Op: check
Msg_type: Error
Msg_text: View 'test.a_view' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
*************************** 3. row ***************************
   Table: test.a_view
      Op: check
Msg_type: error
Msg_text: Corrupt
3 rows in set (0.00 sec)

ERROR:
No query specified
定期优化表

OPTIMIZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name [, tbl_name]
如果您已经删除了表的一大部分,或者如果您已经对含有可变长度行的表(含有VARCHAR, BLOB或TEXT列的表)进行了很多更改,则应使用OPTIMIZE TABLE。被删除的记录被保持在链接清单中,后续的INSERT操作会重新使用旧的记录位置。您可以使用OPTIMIZE TABLE来重新利用未使用的空间,并整理数据文件的碎片。
在多数的设置中,您根本不需要运行OPTIMIZE TABLE。即使您对可变长度的行进行了大量的更新,您也不需要经常运行,每周一次或每月一次即可,只对特定的表运行。
OPTIMIZE TABLE只对MyISAM, BDB和InnoDB表起作用。
对于MyISAM表,OPTIMIZE TABLE按如下方式操作:
如果表已经删除或分解了行,则修复表。
如果未对索引页进行分类,则进行分类。
如果表的统计数据没有更新(并且通过对索引进行分类不能实现修复),则进行更新。

mysql> OPTIMIZE table a;
+--------+----------+----------+-----------------------------+
| Table  | Op       | Msg_type | Msg_text                    |
+--------+----------+----------+-----------------------------+
| test.a | optimize | status   | Table is already up to date |
+--------+----------+----------+-----------------------------+
1 row in set (0.00 sec)

****
以上某些的段落是直接摘自MySQL的中文手册,详细可以直接查看MySQL的帮助手册,这里只是简单指出几种定期优化的方式,需要注意的是无论是ANALYZE,CHECK还是OPTIMIZE在执行期间将对表进行锁定,因此请注意这些操作要在数据库不繁忙的时候执行

****
参考
《MySQL 5.1参考手册》

by 陈于喆

show table status
mysql官方文档在

http://dev.mysql.com/doc/refman/5.1/en/show-table-status.html

这里的rows行是表的行数,但是实际上是不准的。myisam是准的,其他的存储引擎是不准的。要准确的行数就需要使用count(*) 来获取了。

mysql执行大批量删除
执行大批量删除的时候注意要使用上limit

因为如果不用limit,删除大量数据很有可能造成死锁

如果delete的where语句不在索引上,可以先找主键,然后根据主键删除数据库

ps: 平时update和delete的时候最好也加上limit 1 来防止误操作

optimize、Analyze、check、repair维护操作

optimize 数据在插入,更新,删除的时候难免一些数据迁移,分页,之后就出现一些碎片,久而久之碎片积累起来影响性能,这就需要DBA定期的优化数据库减少碎片,这就通过optimize命令。

如对MyisAM表操作:optimize table 表名

对于InnoDB表是不支持optimize操作,否则提示“Table does not support optimize, doing recreate + analyze instead”,当然也可以通过命令:alter table one type=innodb; 来替代。

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

Analyze table 表名

Check检查表或者视图是否存在错误,对 MyISAM 和 InnoDB 存储引擎的表有作用。对于 MyISAM 存储引擎的表进行表检查,也会同时更新关键字统计数据

Repair optimize需要有足够的硬盘空间,否则可能会破坏表,导致不能操作,那就要用上repair,注意INNODB不支持repair操作
生成乱序的id
方法:

使用预设表

比如id和toid的映射

其中id是固定的,toid是随机的。

然后在redis或memcache中记录一个指针值,指向id

当要获取一个新toid的时候,取出指针值,加1,然后去预设表中获取toid

查询和索引
查询的时候必须要考虑到如何命中索引

比如有几个小招:

1 不要在索引列中使用表达式

where mycol *2 < 4

2 不要在like模式的开始位置使用通配符%

where col_name like ‘%string%'

不如

where col_name like ‘string%'

3 避免过多使用mysql自动转换类型,有可能无法用到index

比如

select * from mytbl where str_col=4

但是str_col为字符串,这里其实就隐含了字符串变化

应该使用

select * from mytbl where str_col='4'

索引比表还大就不需要建立索引了吗

索引是按照顺序排列的。所以即使索引比表大,也是可以加快查询速度的。

当然如果索引比表还大首要的任务必须是检查下索引建立地是否有问题

Char和varchar如何选择
char是定长,varchar变长
varchar除了设置了数据之外,还多使用1两个字节定义了数据实际长度。

char会在后面空余的行填充上空字符串

myisam建议使用char。myisam中有个静态表的概念。使用char比使用varchar的查询效率高很多。

innodb建议使用varchar。主要是从节省空间的方面考虑

多个TimeStamp设置默认值
一个表中至多只能有一个字段设置CURRENT_TIMESTAMP

对于下面的需求:

一个表中,有两个字段,createtime和updatetime。

1 当insert的时候,sql两个字段都不设置,会设置为当前的时间
2 当update的时候,sql中两个字段都不设置,updatetime会变更为当前的时间

这样的需求是做不到的。因为你无法避免在两个字段上设置CURRENT_TIMESTAMP

解决办法有几个:

1 使用触发器。

2 将第一个timestamp的default设置为0

3 老老实实在sql语句中使用时间戳。

http://www.jb51.net/article/31872.htm

查询数据表有多少行,多少容量
不要使用select count(*)

使用show table status like ‘table_name'  但是innodb的话会有50%左右的浮动,是个预估值

AUTO_INCREMENT的设置

1 不要设置为int,请设置为unsinged int,auto_increment的范围是根据类型来判定的
2 auto_increment数据列必须要有索引,并且保证唯一性。
3 auto_increment必须有NOT NULL属性
4 auto_increment可以使用

UPDATE table SET seq = LAST_INSERT_ID(seq -1)

mysql的表示时间的字段用什么类型
表示时间可以使用timestamp和datetime来使用

datetime表示的时间可以从0000-00-00:00:00 到9999-12-31:00:00:00

timestamp表示的时间为1970-01-01 08:00:01到2038-01-19 11:14:07

timestamp占用的空间比datetime少,且可以设置时区等功能,所以能使用timestamp的地方尽量使用timestamp

使用timestamp还可以设置

[ON UPDATE CURRENT_TIMESTAMP]

[DEFAULT CURRENT_TIMESTAMP]

myisam和innodb支持外键
myisam不支持外键,innodb支持;

如果你使用创建外键的命令对myisam的表操作,操作不会返回失败,但是是没有外键关联建立起来的。

对一个字段加减语句
经常有需求对一个字段加减会使用

update table set a = a+1

这样是对的

但是如果这样设置:

select a from table

取出数据后a为1

update table set a =2

这样会导致如果在select和update之间有其他事务操作修改这个字段的话,导致最后的设置可能出错。

(0)

相关推荐

  • 实现MySQL定时批量检查表repair和优化表optimize table的shell脚本

    本文介绍mysql定时批量检查表repair和优化表optimize table的shell脚本,对于MySQL数据库的定期维护相当有用!如下所示: #!/bin/bash host_name=192.168.0.123 user_name=jincon.com user_pwd=jincon.com database=my_db_name need_optmize_table=true tables=$(mysql -h$host_name -u$user_name -p$user_pwd $

  • 一个简单的防CC攻击Shell脚本分享

    实现代码: 复制代码 代码如下: #!/bin/shcd /var/log/httpd/cat access_log|awk '{print $1}'|sort|uniq -c|sort -n -r|head -n 20 > acp /dev/null access_logcp /dev/null error_logcp /dev/null limit.shcp /dev/null c#awk '{print $2}' a|awk -F. '{print $1"."$2"

  • mysql 让一个存储过程定时作业的代码

    1.在mysql 中建立一个数据库 test1 语句:create database test1 2.创建表examinfo create table examinfo( id int auto_increment not null, endtime datetime, primary key(id) ); 3 插入数据: insert into examinfo values('1','2011-4-23 23:26:50'); 4 创建存储过程test CREATE PROCEDURE te

  • MySQL定时执行脚本(计划任务)命令实例

    查看event是否开启 复制代码 代码如下: show variables like '%sche%'; 将事件计划开启 复制代码 代码如下: set global event_scheduler =1; 创建存储过程test 复制代码 代码如下: CREATE PROCEDURE test () BEGIN update examinfo SET endtime = now() WHERE id = 14; END; 创建event e_test 复制代码 代码如下: create event

  • MySQL定时备份之使用Linux下的crontab定时备份实例

    1. Mysql备份某个数据库的命令 复制代码 代码如下: ##################################################################  # 备份某个数据库  ################################################################## # root 用户,创建备份目录  mkdir -p /usr/local/cncounter/mysql_dump  cd /usr/local/

  • mysql下优化表和修复表命令使用说明(REPAIR TABLE和OPTIMIZE TABLE)

    查询mysql表是否被损坏命令,如下: # CHECK TABLE 表名 mysql的长期使用,肯定会出现一些问题,一般情况下mysql表无法访问,就可以修复表了,优化时减少磁盘占用空间.方便备份. 表修复和优化命令,如下: #REPAIR TABLE `table_name` 修复表 #OPTIMIZE TABLE `table_name` 优化表 REPAIR TABLE 用于修复被破坏的表. OPTIMIZE TABLE 用于回收闲置的数据库空间,当表上的数据行被删除时,所占据的磁盘空间并

  • MySQL定时器开启、调用实现代码

    创建测试表 复制代码 代码如下: CREATE TABLE t ( v VARCHAR(100) NOT NULL ) ENGINE INNODB DEFAULT CHARSET=utf8; 创建定时器 调用的存储过程 DELIMITER $$ DROP PROCEDURE IF EXISTS e_test $$ CREATE PROCEDURE e_test() BEGIN INSERT INTO t VALUES('1'); END $$ DELIMITER ; 要使定时起作用 MySQL的

  • windows下实现定时重启Apache与MySQL方法

    采用at命令添加计划任务.有关使用语法可以到window->"开始"->运行"cmd"->执行命令"at /",这样界面中就会显示at命令的语法.下面我们讲解下如何让服务器定时启动apache与mysql: 1.在c:盘根目录新建一个autostartserver.bat文件,然后右键编辑,将文件内容设为如下后保存: 复制代码 代码如下: @ECHO OFF net stop apache2 net start apache2

  • MySQL定期分析检查与优化表的方法小结

    定期分析表 ANALYZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name [, tbl_name] 本语句用于分析和存储表的关键字分布.在分析期间,使用一个读取锁定对表进行锁定.这对于MyISAM, BDB和InnoDB表有作用.对于MyISAM表,本语句与使用myisamchk -a相当. MySQL使用已存储的关键字分布来决定,当您对除常数以外的对象执行联合时,表按什么顺序进行联合. mysql> analyze table a; +--------

  • MySQL之存储过程按月创建表的方法步骤

    具体不多说,直接上代码.欢迎一起交流和学习. 创建一个按月创建表的存储过程,SQL语句如下: DELIMITER // DROP PROCEDURE IF EXISTS create_table_by_month // CREATE PROCEDURE `create_table_by_month`() BEGIN #--提前申明变量,后面会用到 DECLARE nextMonth varchar(20); DECLARE nextTABLE varchar(20); DECLARE csql

  • MySQL查询结果复制到新表的方法(更新、插入)

    MySQL中可以将查询结果复制到另外的一张表中,复制的话通常有两种情况,一种是更新已有的数据,另一种是插入一条新记录.下面通过例子来说明.首先构建两个测试表. 表t1: 表t2: 1.如果t2表中存在score值,将score更新到t1表中.方法如下: UPDATE t1,t2 SET t1.score = t2.score WHERE t1.id = t2.id AND t2.score IS NOT NULL 这就是将查询结果作为条件更新另一张表,当然,t2也可以是更为复杂的一个查询结果而不

  • mysql5.7及mysql 8.0版本修改root密码的方法小结

    mysql5.7版本: 方法1: 用SET PASSWORD命令 格式:mysql> set password for 用户名@localhost = password('新密码'); 例子:mysql> set password for root@localhost = password('123'); mysql5.7和mysql8.0以上都可以用 方法2:用mysqladmin 格式:mysqladmin -u用户名 -p password 新密码 例子:mysqladmin -uroo

  • MySQL利用procedure analyse()函数优化表结构

    简介 procedure analyse()函数是MySQL内置的对MySQL字段值进行统计分析后给出建议的字段类型. 语法 procesure analyse(max_elements,max_memory) max_elements 指定每列非重复值的最大值,当超过这个值的时候,MySQL不会推荐enum类型. max_memory analyse()为每列找出所有非重复值所采用的最大内存大小. 实战演练 # 对t1表所有的列进行分析 wing@3306>show create table

  • mysql 导入导出数据库、数据表的方法

    Linux下均在控制台下操作.导入数据库:前提:数据库和数据表要存在(已经被创建) (1)将数据表 test_user.sql 导入到test 数据库的test_user 表中[root@test ~]# mysql -uroot -p test < /www/web/test/test_user.sql (2) 将数据库 test.sql 导入到 test 数据库test 中[root@test ~]# mysql -uroot -p test < /www/web/test/test.sq

  • mysql中Table is read only的解决方法小结

    如果是使用中的数据库突然出现些类问题 在Linux下面执行下面命令就可以了,当然你要找到你的mysql目录 linux中 复制代码 代码如下: /usr/local/mysql/bin/mysqladmin -u root -p flush-tables windows中 可以在cmd中执行lush-tables 也可以在phpmyadmin 直利用修复表进行修改 如果是导入还原数据 ,所以将该数据库文件夹下面所有表文件chmod成777,chown成"_mysql",但这次问题更严重

  • Nginx服务器高性能优化的配置方法小结

    通常来说,一个优化良好的 Nginx Linux 服务器可以达到 500,000 – 600,000 次/秒 的请求处理性能,然而我的 Nginx 服务器可以稳定地达到 904,000 次/秒 的处理性能,并且我以此高负载测试超过 12 小时,服务器工作稳定. 这里需要特别说明的是,本文中所有列出来的配置都是在我的测试环境验证的,而你需要根据你服务器的情况进行配置: 从 EPEL 源安装 Nginx: yum -y install nginx 备份配置文件,然后根据你的需要进行配置: cp /e

  • MySQL中基本的用户和权限管理方法小结

    MySQL 默认有个root用户,但是这个用户权限太大,一般只在管理数据库时候才用.如果在项目中要连接 MySQL 数据库,则建议新建一个权限较小的用户来连接. 在 MySQL 命令行模式下输入如下命令可以为 MySQL 创建一个新用户: CREATE USER username IDENTIFIED BY 'password'; 新用户创建完成,但是此刻如果以此用户登陆的话,会报错,因为我们还没有为这个用户分配相应权限,分配权限的命令如下: GRANT ALL PRIVILEGES ON *.

  • MYSQL数据表损坏的原因分析和修复方法小结(推荐)

    1.表损坏的原因分析 以下原因是导致mysql 表毁坏的常见原因: 1. 服务器突然断电导致数据文件损坏. 2. 强制关机,没有先关闭mysql 服务. 3. mysqld 进程在写表时被杀掉. 4. 使用myisamchk 的同时,mysqld 也在操作表. 5. 磁盘故障. 6. 服务器死机. 7. mysql 本身的bug . 2.表损坏的症状 一个损坏的表的典型症状如下: 1 .当在从表中选择数据之时,你得到如下错误: Incorrect key file for table: '...

随机推荐