的输出show engine innodb status
具有作为数字的历史列表长度,但是该输出很难解析,并且当您想要的只是一个值时,数据太多了。该值是否可以在其他地方以一行的形式获取?
Pedro Werneck's questions
我在 Amazon RDS 上有一个 MySQL 5.6,用于测试一些数据归档脚本。我正在根据“updated_date”列和索引删除最旧的数据。奇怪的是,在删除了几百万行之后,我的脚本卡在了它为确定数据边界所做的初始查询上。
我运行这样的查询:
SELECT min(updated_date) as oldest, max(updated_date) AS newest FROM `order`;
此查询的explain
命令显示:
'1', 'SIMPLE', NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'Select tables optimized away'
因此,它应该几乎立即命中索引并运行,并且在测试开始时确实如此,但是现在,在删除数百万行之后,它会在“优化”状态中停留几分钟。
脚本是唯一在数据库上运行的东西。
关于它有什么问题的任何想法?删除大量这样的行时,我应该做些什么吗?optimize table
即使我不使用,我是否必须跑步delete quick
?
更新#1
结果来自show table status like 'order'
:
Name,Engine,Version,Row_format,Rows,Avg_row_length,Data_length,Max_data_length,Index_length,Data_free,Auto_increment,Create_time,Update_time,Check_time,Collation,Checksum,Create_options,Comment
order,InnoDB,10,Compact,568037197,280,159252496384,0,180806041600,37692112896,4052226884,"2015-01-26 17:27:20",NULL,NULL,utf8_general_ci,NULL,,
结果select count(*) from order
是 618376777 行。
不幸的是,我不能在这里发布整个架构,但它与问题有关,结果show create table order
是:
CREATE TABLE `order` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
// 31 data columns here
`updated_date` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `ix_order_updated_date` (`updated_date`),
// 9 indexes here
) ENGINE=InnoDB AUTO_INCREMENT=4052226884 DEFAULT CHARSET=utf8;
更新#2
通过在两个查询中分离 min() 和 max() 调用,我注意到只有 min() 查询受到影响。max() 几乎立即返回,因此看起来 min() 正在遍历所有存在但现在为空的索引条目的索引。除了重建索引之外,还有什么方法可以防止这种情况发生吗?
更新#3
RickJames 通过有关更改缓冲的提示解决了这个问题,但是完全禁用它会损害所有插入、删除和更新的性能。最终,我发现在生产服务器上刷新更改缓冲区所需的时间是合理的,所以问题对我来说解决了,但如果你在带有磁性存储的低端服务器上遇到同样的问题,祝你好运。
众所周知,InnoDB 表中随机 UUID 作为 PK 的性能如何随着其大小的增加而急剧下降。非 PK UUID 列的 UNIQUE 索引会产生相同的影响吗?
UUID 是第 4 版,随机的,存储为二进制 (16)。
我有一个只有两列的 InnoDB 表,一个 VARCHAR(20) 和一个 DATETIME,以及大约 400 万行。该表用作其他表的黑名单,并且会不时从 csv 文件中截断和重新创建。除此之外没有涉及写入,它仅用于 SELECT 检查是否存在键,它总是命中 VARCHAR 列的索引。
问题是,我所有系统中的每一个操作都必须一直查询这个表,因为如果有匹配项,这是非常罕见的,则必须立即中止该操作。从我的应用程序分析中,我们花费了大约 10% 的数据库时间来读取它。
我正在考虑为此表使用内存引擎。这个想法是用只加载 csv 文件而不是整个数据导入操作的 CSV 引擎创建一个基表,以及一个初始化脚本来填充内存表。我假设 VARCHAR 列上的 HASH 索引对于简单查找来说会更快,但我不确定它在我拥有的几乎 100% 的未命中率下是否表现良好。
这是提高我的查找速度的好主意吗?
我需要找到表 A 中所有行的 ID,而表 B 上没有匹配的行。按照这个问题的答案,我使用这样的左连接:
select A.id from A left join B on B.id_A = A.id where B.id_A is null;
它工作得很好。但是现在我需要使用附加条件进行相同的查询以进行匹配,这意味着我需要找到表 A 中所有行的 ID,而表 B 上没有匹配行,其列 c 的值为 x。如果我尝试类似的东西:
select A.id from A left join B on B.id_A = A.id where B.id_A is null and B.c = x;
它显然给了我一个空的结果集。
到目前为止,我想做到这一点的唯一方法是使用带有“不存在”子句的 B 子查询:
select A.id from A where not exists (select id from B where B.id_A = A.id and B.c = x);
关于如何在不使用子查询的情况下通过连接执行此操作的任何想法?