我们正在两个数据库表之间进行更新查询,速度非常慢。如下所示:执行查询需要30 天。
一个表,lab.list,包含大约940,000条记录,另一个,mind.list大约3,700,000(370万) 当满足两个BETWEEN条件时,更新设置字段。这是查询:
UPDATE lab.list L , mind.list M SET L.locId = M.locId WHERE L.longip BETWEEN M.startIpNum AND M.endIpNum AND L.date BETWEEN "20100301" AND "20100401" AND L.locId = 0
就像现在一样,查询每8秒执行大约1次更新。
我们也在同一个数据库中使用mind.list表进行了尝试,但这与查询时间无关。
UPDATE lab.list L, lab.mind M SET L.locId = M.locId WHERE longip BETWEEN M.startIpNum AND M.endIpNum AND date BETWEEN "20100301" AND "20100401" AND L.locId = 0;
有没有办法加快这个查询?基本上恕我直言,它应该使数据库的两个子集: mind.list.longip BETWEEN M.startIpNum和M.endIpNum lab.list.date BETWEEN“20100301”和“20100401”
然后更新这些子集的值。在某个地方,我认为我犯了一个错误,但在哪里?也许有更快的查询可能吗?
我们尝试了log_slow_queries,但这表明它确实检查了数百万行,可能会一直上升到3331 gigarows。
技术信息:
答案 0 :(得分:1)
我首先尝试按此顺序对startIpNum,endIpNum,locId进行索引。即使用于更新,locId也不会用于SELECTing。
出于同样的原因,我在locId,date和longip(在第一个分块中没有使用,这应该在日期运行)上对此命令进行索引。
那么为startIpNum和endIpNum分配了哪种数据类型?对于IPv4,最好转换为INTEGER并使用INET_ATON和INET_NTOA进行用户I / O.我假设你已经这样做了。
要运行更新,您可能会尝试使用临时表对M数据库进行分段。那就是:
* select all records of lab in the given range of dates with locId = 0 into a temporary table TABLE1.
* run an analysis on TABLE1 grouping IP addresses by their first N bits (using AND with a suitable mask: 0x80000000, 0xC0000000, ... 0xF8000000... and so on, until you find that you have divided into a "suitable" number of IP "families". These will, by and large, match with startIpNum (but that's not strictly necessary).
* say that you have divided in 1000 families of IP.
* For each family:
* select those IPs from TABLE1 to TABLE3.
* select the IPs matching that family from mind to TABLE2.
* run the update of the matching records between TABLE3 and TABLE2. This should take place in about one hundred thousandth of the time of the big query.
* copy-update TABLE3 into lab, discard TABLE3 and TABLE2.
* Repeat with next "family".
这不是很理想,但如果略微改进的索引没有帮助,我真的看不到那么多选项。
答案 1 :(得分:0)
最后,查询太大或太麻烦,无法填充mysql。索引后即使。在高端Sybase服务器上使用相同的数据测试相同的查询也需要3个小时。
所以我们放弃了在数据库服务器上做到这一切的想法,然后又回到了脚本语言。
我们在python中做了以下事情:
所有这些更新一起大约需要5分钟,所以这是一个巨大的进步!
结论:
在数据库框之外思考!