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

本文介绍了一种优化数据库表的方法,特别是针对InnoDB表,通过执行特定脚本可以在不改变Auto_increment值的情况下提升查询速度约10%。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

数据库中的表不断在增大,删除/更新/添加的多了,表的性能就会降低。定期的执行 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% 左右。
-- 使用InnoDB引擎支持事务 CREATE DATABASE travel_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -- 景点(空间索引优化位置查询) CREATE TABLE attractions ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100) NOT NULL, description TEXT, location POINT NOT NULL SRID 4326, -- 空间数据类型 price DECIMAL(10, 2), capacity INT, SPATIAL INDEX(location) ) ENGINE=InnoDB; -- 酒店(JSON类型存储动态属性) CREATE TABLE hotels ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100) NOT NULL, address VARCHAR(200), room_types JSON, -- 存储房型及价格 {'standard': 200, 'deluxe': 400} amenities JSON -- 设施 {'wifi': true, 'parking': false} ) ENGINE=InnoDB; -- 会员(分区优化查询) CREATE TABLE members ( id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50) UNIQUE NOT NULL, password CHAR(60) NOT NULL, -- 存储bcrypt哈希 level ENUM('basic', 'silver', 'gold') DEFAULT 'basic', points INT DEFAULT 0, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB PARTITION BY RANGE (YEAR(created_at)) ( PARTITION p0 VALUES LESS THAN (2023), PARTITION p1 VALUES LESS THAN (2024) ); -- 线路(使用全文索引) CREATE TABLE tours ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100) NOT NULL, description TEXT, attractions JSON, -- 包含的景点ID [1, 3, 5] price DECIMAL(10, 2), FULLTEXT INDEX (name, description) ) ENGINE=InnoDB; -- 预定(事务处理) CREATE TABLE bookings ( id INT AUTO_INCREMENT PRIMARY KEY, member_id INT NOT NULL, item_type ENUM('attraction', 'hotel', 'tour') NOT NULL, item_id INT NOT NULL, quantity INT NOT NULL, booking_date DATETIME NOT NULL, status ENUM('pending', 'confirmed', 'cancelled') DEFAULT 'pending', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (member_id) REFERENCES members(id) ON DELETE CASCADE ) ENGINE=InnoDB; 讲上述数据库设计的代码改成SQL server的代码
06-18
[SQL] Query gudingzichan start [ERR] 1075 - Incorrect table definition; there can be only one auto column and it must be defined as a key [ERR] CREATE TABLE `users` ( `id` int(10) NOT NULL AUTO_INCREMENT, `name` varchar(10) NOT NULL, `password` varchar(10) NOT NULL, `tell` varchar(11) NOT NULL, `jibei` char(1) NULL, `zhuangtai` char(1) NULL, PRIMARY KEY (`id`) ); CREATE TABLE `liebie` ( `id` int(10) NOT NULL AUTO_INCREMENT, `name` varchar(100) NOT NULL, `text` varchar(255) NULL, `nianxian` varchar(5) NULL, `fenlei` varchar(10) NULL, `zhuangtai` char(1) NULL, PRIMARY KEY (`id`) ); CREATE TABLE `guanli` ( `id` int(10) NOT NULL AUTO_INCREMENT, `bumen` int(10) NULL, `fuzeren` int(10) NULL, `kuguan` int(10) NULL, `caiwu` int(10) NULL, `zhuangtai` char(1) NULL, PRIMARY KEY (`id`) ); CREATE TABLE `zichan` ( `id` int(10) NOT NULL AUTO_INCREMENT, `liebie` int(10) NULL, `bumen` int(10) NULL, `name` varchar(10) NOT NULL, `guige` varchar(100) NULL, `danwei` int(1) NULL, `year` varchar(50) NULL, `fangshi` int(1) NULL, `yuanzhi` varchar(50) NULL, `beizhu` varchar(255) NULL, `zhuangtai` char(1) NULL, PRIMARY KEY (`id`) ); CREATE TABLE `danwei` ( `id` int(10) NOT NULL AUTO_INCREMENT, `name` varchar(5) NULL, `zhuangtai` char(1) NULL, PRIMARY KEY (`id`) ); CREATE TABLE `fangshi` ( `id` int(10) NOT NULL AUTO_INCREMENT, `name` varchar(5) NULL, `zhuangtai` char(1) NULL, PRIMARY KEY (`id`) ); CREATE TABLE `bumen` ( `id` int(10) NOT NULL AUTO_INCREMENT, `name` varchar(50) NULL, `zhuangtai` char(1) NULL, PRIMARY KEY (`id`) ); CREATE TABLE `zichan_mingxi` ( `id` int(10) NOT NULL AUTO_INCREMENT, `fenlei` int(10) NULL, `bianma` int(8) ZEROFILL NOT NULL AUTO_INCREMENT, `zichan` int(10) NULL, `shiyongren` int(10) NULL, `zhuangtai` char(1) NULL, PRIMARY KEY (`id`, `bianma`) ); CREATE TABLE `weixiu` ( `id` int(10) NOT NULL AUTO_INCREMENT, `users` int(10) NULL, `gongzhong` varchar(50) NULL, `zhuangtai` char(1) NULL, PRIMARY KEY (`id`) ); CREATE TABLE `weixui_mingxi` ( `id` int(10) NOT NULL AUTO_INCREMENT, `weixiuren` int(10) NULL, `zichanbianma` int(10) NULL, `zhuangtai` char(1) NULL, PRIMARY KEY (`id`) ); CREATE TRIGGER ON `weixui_mingxi` FOR EACH ROW ; ALTER TABLE `zichan` ADD CONSTRAINT `zichan_liebie` FOREIGN KEY (`liebie`) REFERENCES `liebie` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; ALTER TABLE `zichan` ADD CONSTRAINT `zichan_danwei` FOREIGN KEY (`danwei`) REFERENCES `danwei` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; ALTER TABLE `zichan` ADD CONSTRAINT `zicahn_fangshi` FOREIGN KEY (`fangshi`) REFERENCES `fangshi` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; ALTER TABLE `zichan` ADD CONSTRAINT `zichan_bumen` FOREIGN KEY (`bumen`) REFERENCES `bumen` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; ALTER TABLE `guanli` ADD CONSTRAINT `guanli_bumen` FOREIGN KEY (`bumen`) REFERENCES `bumen` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; ALTER TABLE `guanli` ADD CONSTRAINT `guanli_fuzeren` FOREIGN KEY (`fuzeren`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; ALTER TABLE `guanli` ADD CONSTRAINT `guanli_kuguan` FOREIGN KEY (`kuguan`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; ALTER TABLE `guanli` ADD CONSTRAINT `guanli_caiwu` FOREIGN KEY (`caiwu`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; ALTER TABLE `zichan_mingxi` ADD CONSTRAINT `zichanmingxi_fenlei` FOREIGN KEY (`fenlei`) REFERENCES `liebie` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; ALTER TABLE `zichan_mingxi` ADD CONSTRAINT `zichanmingxi_zichan` FOREIGN KEY (`zichan`) REFERENCES `zichan` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; ALTER TABLE `zichan_mingxi` ADD CONSTRAINT `zichanmingxi_shiyongren` FOREIGN KEY (`shiyongren`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; ALTER TABLE `weixiu` ADD CONSTRAINT `weixiu_users` FOREIGN KEY (`users`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE; ALTER TABLE `weixui_mingxi` ADD CONSTRAINT `weixiumingxi_weixiuren` FOREIGN KEY (`weixiuren`) REFERENCES `weixiu` (`id`) ON DELETE C [SQL] Finished with error
最新发布
08-05
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值