【发布时间】:2014-08-28 14:33:59
【问题描述】:
我希望有人可以提出建议,但我在处理以下联接语句时遇到了很长的处理时间,并希望获得一些关于提高性能的建议。两个表都有数百万条记录,并且我有列索引,但是运行这个连接仍然需要 70 多个小时。
update <table x> a
left join <table y> b
on a.PARENT_ID=b.ID and a.LOAD_ID=b.LOADID
set a.DATETIME=str_to_date(b.`DateTime`, '%m/%d/%Y %H:%i:%s'), a.ROOM_ID=b.ConID, a.STATUS='Exited'
where a.PARENT_ID=b.ID and a.LOAD_ID=b.LOADID and a.PROCESSING_FLAG = 0 and b.PROCESSING_FLAG = 0
所以表 x 有 66m 条记录,而表 y 有 44m,但是使用 PROCESSING_FLAG 它不会将所有 66m 记录连接到 44m 记录,只是一个子集。我在 a.Parent_Id、b.ID、a.Load_ID、b.LoadID、a.Room_ID、b.ConID、a.Processing_Flag 和 b.Processing_Flag 上有列索引。两个表都使用 MISAM,我使用的是 MySQL 5.6.17。
我能做些什么来提高这个语句的性能吗?作为第一步,我正在考虑将密钥缓冲区增加到 6G。
【问题讨论】:
-
您是否尝试通过 EXPLAIN 运行它以查看它是否真的在使用您认为的索引?
-
PROCESSING_FLAG 显然是 0 或 1,因此它的基数是无用的 - 无论您是否索引它,MySQL 仍然会遍历整个数据集以确定不需要某些记录。我没有看到在该查询中有效使用索引的单一令人满意的标准。下一个愚蠢的事情是您出于某种奇怪的原因使用 MyISAM,因此您受到 I/O 限制,因为 RAM 很可能不用于存储工作数据集的热副本。我怀疑如果不使用可以有效利用 RAM 的更先进的存储引擎,这可以进行任何优化。
-
我还没有,因为该语句仍在运行,并且锁定了表。
-
是处理标志设置为位,因此为 1 或 0。我的想法是我在卡盘中获取数据,并且每个卡盘都得到处理。所以我想要一种只处理新数据而不是旧数据的方法。
-
使用MYISAM,因为我在某处读到它更快。我不使用 Innodb,因为这不是一个应用程序,所以不需要主键和外键,并且确实需要 ACID 合规性。我倾向于得到非规范化的数据。
标签: mysql performance