数据库中的表不断在增大,删除/更新/添加的多了,表的性能就会降低。定期的执行 OPTIMIZE TABLE 很有效的提高查询速度。
不过,对于 InnoDB,如果一旦进行 OPTIMIZE TABLE 操作,就会把 Auto_increment 变更为目前的最大的值 +1。Rails 的数据表默认是以 id 作为主键的,而且它就是把 Auto_increment 的值作为自己的值。这样,如果一个数据表最后添加的记录被删除了,在执行 OPTIMIZE TABLE 后,那些被删除的 id 就有可能被重新使用。如果你是定期的表的导入导出,或者以 id 为目录存储文件,就会产生大问题了。
这个script主要是对数据库进行 OPTIMIZE TABLE 操作,而不会改变 Auto_increment 的值。
建议专门建立用于 OPTIMIZE TABLE 的用户(这里设定的用户名和密码都是 optimize),需要给他表的 SELECT、INSERT、ALTER、LOCK TABLES 权限。
#!/usr/bin/env ruby
require "mysql"
USER = "optimize"
PASSWORD = "optimize"
SOCKET = "/var/lib/mysql/mysql.sock"
def optimize_host(host)
begin
# connect to the MySQL server
dbh = Mysql.real_connect(host, USER, PASSWORD, nil, nil, SOCKET)
puts "========== #{host} =========="
dbh.list_dbs.each do |database|
next if database == 'mysql' || database == 'information_schema' || database == 'test'
puts "#{database} Tables"
dbh.select_db(database)
tables = dbh.query("SHOW TABLE STATUS;")
tables.each_hash do |table|
name = table["Name"]
next if name == 'schema_info'
puts "Optimize Tables #{name}"
engine = table["Engine"]
puts "Engine: " + engine.to_s
if engine == 'MyISAM'
dbh.query("OPTIMIZE TABLES #{name};")
elsif engine == 'InnoDB'
dbh.query("LOCK TABLES #{name} WRITE;")
autoid = nil
dbh.query("SHOW TABLE STATUS LIKE '#{name}';").each_hash do |row|
autoid = row["Auto_increment"]
end
puts "Auto_increment: " + autoid.to_s
if autoid.nil?
dbh.query("ALTER TABLE #{name} ENGINE=InnoDB;")
else
dbh.query("ALTER TABLE #{name} ENGINE=InnoDB AUTO_INCREMENT=#{autoid};")
end
dbh.query("UNLOCK TABLES;")
elsif
puts "Warning: Unknown table engine.............................................."
end
end
tables.free
end
rescue Mysql::Error => e
puts "Error code: #{e.errno}"
puts "Error message: #{e.error}"
puts "Error SQLSTATE: #{e.sqlstate}" if e.respond_to?("sqlstate")
ensure
# disconnect from server
dbh.close if dbh
end
end
ARGV.each do |host|
optimize_host(host)
end
需要安装 Ruby/MySQL 才可以,如果没有安装,可以 require 一下 ActiveRecord 中的 mysql.rb 文件。还要说明一下,对已 InnoDB 表,大多数的 ALTER TABLE 操作和 OPTIMIZE TABLE 操作是等价的。
我们的数据库在执行了 OPTIMIZE TABLE 后,查询速度提升了 10% 左右。
分享到:
- 2009-01-16 11:18
- 浏览 2501
- 评论(2)
- 论坛回复 / 浏览 (2 / 3212)
- 查看更多
相关推荐
7. **监控和调整**:在高并发场景下,要关注`auto_increment`的增长情况,适时进行表分区或调整主键策略,以优化性能。 综上所述,理解和正确使用`auto_increment`对于维护MySQL数据库的正常运行至关重要。无论是...
- `REPLACE`命令不会改变WHERE子句中出现的AUTO_INCREMENT值,除非没有明确指定。 4. **last_insert_id()函数**: - 该函数用于获取自增列自动生成的最后一个编号,仅与当前会话相关。如果没有生成新的自增值,...
当配置主主复制时,为了避免冲突,两台服务器的`auto_increment_offset`应分别设置为1和2,而`auto_increment_increment`应设置为2。 2. **auto_increment_increment**:它定义了自增长字段每次递增的量,默认是1,...
为了防止"脑裂"和自增ID冲突,通常会设置不同的`auto_increment_increment`和`auto_increment_offset`。此外,可以利用MySQL 5.7+的多线程复制功能减少延迟,或者使用半同步复制(semi-sync)实现接近零延迟,但可能...
对于增加或删除`AUTO_INCREMENT`属性,同样可以只修改表的元数据来实现。 在描述中还提到,一次添加多个字段相比于逐个添加会更节省时间。例如,一次性添加三个字段比分开添加要快得多。这是因为一次操作中,MySQL...
以下是对一些核心知识点的详细解释: 1. **MySQL 锁机制**: - **表级锁**:适用于简单查询和批量更新,因为加锁速度快,但并发度低,可能导致大量等待。 - **行级锁**:提供更高的并发性,适用于频繁的读写操作...
3. **Heap表**:Heap表是内存中的临时存储表,用于高速处理,但不支持BLOB或TEXT字段,只允许基本的比较运算符,不支持AUTO_INCREMENT,索引不能为NULL。 4. **默认端口**:MySQL服务器默认监听的端口是3306。 5. ...
3. HEAP表是内存中的临时表,用于快速存储,不支持BLOB或TEXT字段,不支持AUTO_INCREMENT,索引不可为NULL。 4. MySQL的默认端口号是3306。 5. 与Oracle相比,MySQL的优势在于开源、免费、便携性、GUI工具支持以及...
- `AUTO_INCREMENT`定义自增列,常用于主键。 - `DATA DIRECTORY`和`INDEX DIRECTORY`可分别设置数据文件和索引文件的存储位置。 6. **表的维护**: - 定期进行`OPTIMIZE TABLE`操作,以重组和压缩表数据,提高...
这些知识点涵盖了数据库的创建、删除、查询、更新等基本操作,并且包括了表结构的修改与优化等内容。 ### 一、启动与停止MySQL服务 #### 启动MySQL服务: ``` net start mysql ``` #### 停止MySQL服务: ``` ...
- 不支持AUTO_INCREMENT - 索引字段不可为NULL 4. **默认端口**: - MySQL服务器默认监听的端口号是3306。 5. **与Oracle相比的优势**: - 开源,免费 - 便携式 - 带有命令行工具和GUI工具 - 高性能查询...
3. HEAP表是一种内存中的临时表,不支持BLOB或TEXT字段,不支持AUTO_INCREMENT,且索引不可为NULL,适合临时高速存储。 4. MySQL服务器的默认端口是3306。 5. MySQL相比Oracle的优势在于开源、便携性、GUI工具、...
3. **Heap表**:Heap表是内存中的临时存储结构,不支持BLOB或TEXT字段,只允许基本的比较操作,不支持AUTO_INCREMENT,也不能有NULL索引。 4. **FLOAT与DOUBLE的区别**:FLOAT存储8位精度,4字节,而DOUBLE存储18位...
在创建学生表的例子中,我们看到如何定义不同的列,如主键(PRIMARY KEY)、自动增长(AUTO_INCREMENT)、非空约束(NOT NULL)以及不同数据类型的使用,如INT、VARCHAR等。这些基础概念是理解数据库操作的核心。 ...
ALTER TABLE table_name AUTO_INCREMENT=1; ``` 最后,当MySQL占用内存过大时,可以通过优化MySQL的配置文件来减少内存消耗。配置文件通常位于`/etc/my.cnf`,在`[mysqld]`段落下,你可以调整如下参数: - `innodb...
在MySQL中,创建表时可以为字段设置自增(AUTO_INCREMENT)属性,每次插入新行时,该字段的值会自动递增。然而,自增ID是有上限的,对于INT类型,上限是2^32-1。当达到这个上限,尝试插入新行时,MySQL会返回主键...
27. 多列索引的创建可以结合多个字段,如`CREATE TABLE student(id int(10) auto_increment primary key not null, name varchar(30) notnull, birthday varchar(30) notnull, INDEX idx_name_birthday(name, ...
在MySQL数据库中,自增ID(AUTO_INCREMENT)是一个非常常见的特性,它在创建表时用于生成唯一的标识符,通常作为主键。这篇文章将深入探讨关于MySQL自增ID的一些关键知识点。 1. **为什么建议将自增列设为主键?** ...