`
秦朝古月
  • 浏览: 227563 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

不改变Auto_increment,对InnoDB表进行优化

阅读更多
数据库中的表不断在增大,删除/更新/添加的多了,表的性能就会降低。定期的执行 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% 左右。
分享到:
评论
2 楼 rainux 2009-04-25  
就是把当前的 auto_increment 值保存出来,优化完表之后再写回去。
1 楼 wcily123 2009-04-24  
很有深度,没怎么看明白。

相关推荐

    Mysql auto_increment 重新计数(让id从1开始)

    7. **监控和调整**:在高并发场景下,要关注`auto_increment`的增长情况,适时进行表分区或调整主键策略,以优化性能。 综上所述,理解和正确使用`auto_increment`对于维护MySQL数据库的正常运行至关重要。无论是...

    mysql自增字段重排 mysql删除表后自增字段从1开始.pdf

    - `REPLACE`命令不会改变WHERE子句中出现的AUTO_INCREMENT值,除非没有明确指定。 4. **last_insert_id()函数**: - 该函数用于获取自增列自动生成的最后一个编号,仅与当前会话相关。如果没有生成新的自增值,...

    mysql全局变量详解[收集].pdf

    当配置主主复制时,为了避免冲突,两台服务器的`auto_increment_offset`应分别设置为1和2,而`auto_increment_increment`应设置为2。 2. **auto_increment_increment**:它定义了自增长字段每次递增的量,默认是1,...

    MySQL数据库双活同步复制方案详解.pdf

    为了防止"脑裂"和自增ID冲突,通常会设置不同的`auto_increment_increment`和`auto_increment_offset`。此外,可以利用MySQL 5.7+的多线程复制功能减少延迟,或者使用半同步复制(semi-sync)实现接近零延迟,但可能...

    关于表添加多个字段的速度问题1

    对于增加或删除`AUTO_INCREMENT`属性,同样可以只修改表的元数据来实现。 在描述中还提到,一次添加多个字段相比于逐个添加会更节省时间。例如,一次性添加三个字段比分开添加要快得多。这是因为一次操作中,MySQL...

    MySQL终级面试题,提升你的内力,给你面试助力

    以下是对一些核心知识点的详细解释: 1. **MySQL 锁机制**: - **表级锁**:适用于简单查询和批量更新,因为加锁速度快,但并发度低,可能导致大量等待。 - **行级锁**:提供更高的并发性,适用于频繁的读写操作...

    SQL优化面试专题及答案.pdf

    3. **Heap表**:Heap表是内存中的临时存储表,用于高速处理,但不支持BLOB或TEXT字段,只允许基本的比较运算符,不支持AUTO_INCREMENT,索引不能为NULL。 4. **默认端口**:MySQL服务器默认监听的端口是3306。 5. ...

    精选常见mysql五十五道面试题目

    3. HEAP表是内存中的临时表,用于快速存储,不支持BLOB或TEXT字段,不支持AUTO_INCREMENT,索引不可为NULL。 4. MySQL的默认端口号是3306。 5. 与Oracle相比,MySQL的优势在于开源、免费、便携性、GUI工具支持以及...

    一千行 mysql 学习笔记.docx

    - `AUTO_INCREMENT`定义自增列,常用于主键。 - `DATA DIRECTORY`和`INDEX DIRECTORY`可分别设置数据文件和索引文件的存储位置。 6. **表的维护**: - 定期进行`OPTIMIZE TABLE`操作,以重组和压缩表数据,提高...

    MySql基本操作.txt

    这些知识点涵盖了数据库的创建、删除、查询、更新等基本操作,并且包括了表结构的修改与优化等内容。 ### 一、启动与停止MySQL服务 #### 启动MySQL服务: ``` net start mysql ``` #### 停止MySQL服务: ``` ...

    MySQL55题答案.pdf

    - 不支持AUTO_INCREMENT - 索引字段不可为NULL 4. **默认端口**: - MySQL服务器默认监听的端口号是3306。 5. **与Oracle相比的优势**: - 开源,免费 - 便携式 - 带有命令行工具和GUI工具 - 高性能查询...

    2022年MySQL面试题(含答案)

    3. HEAP表是一种内存中的临时表,不支持BLOB或TEXT字段,不支持AUTO_INCREMENT,且索引不可为NULL,适合临时高速存储。 4. MySQL服务器的默认端口是3306。 5. MySQL相比Oracle的优势在于开源、便携性、GUI工具、...

    java常见面试题(史上最全最经典)

    3. **Heap表**:Heap表是内存中的临时存储结构,不支持BLOB或TEXT字段,只允许基本的比较操作,不支持AUTO_INCREMENT,也不能有NULL索引。 4. **FLOAT与DOUBLE的区别**:FLOAT存储8位精度,4字节,而DOUBLE存储18位...

    数据库+mysql+面试题

    在创建学生表的例子中,我们看到如何定义不同的列,如主键(PRIMARY KEY)、自动增长(AUTO_INCREMENT)、非空约束(NOT NULL)以及不同数据类型的使用,如INT、VARCHAR等。这些基础概念是理解数据库操作的核心。 ...

    MySQL使用中遇到的问题记录

    ALTER TABLE table_name AUTO_INCREMENT=1; ``` 最后,当MySQL占用内存过大时,可以通过优化MySQL的配置文件来减少内存消耗。配置文件通常位于`/etc/my.cnf`,在`[mysqld]`段落下,你可以调整如下参数: - `innodb...

    Mysql join联表及id自增实例解析

    在MySQL中,创建表时可以为字段设置自增(AUTO_INCREMENT)属性,每次插入新行时,该字段的值会自动递增。然而,自增ID是有上限的,对于INT类型,上限是2^32-1。当达到这个上限,尝试插入新行时,MySQL会返回主键...

    国家开放大学4046数据库运维考试资料精简版.doc

    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的这些你可能还不知道

    在MySQL数据库中,自增ID(AUTO_INCREMENT)是一个非常常见的特性,它在创建表时用于生成唯一的标识符,通常作为主键。这篇文章将深入探讨关于MySQL自增ID的一些关键知识点。 1. **为什么建议将自增列设为主键?** ...

Global site tag (gtag.js) - Google Analytics