mysql数据表规模90000000(九千万)左右,怎么优化查询?

表结构: url_id(int), word_id(int), word_location(int) word_id建了index 执行语句: select * from table where word_id in (word_id1, word_id2.....);

1 个回答

  • 宁大
    快乐出现的时候,就好好享受快乐。
    一般来说,**9千万级别的表,mysql单机是完全可以处理的,用不着分表。** 给出的信息严重不足: 1.表中只有这三个column,还是还有其它的?请给出完整的表结构,包括所有的index和constraint 2.表文件的物理大小?GB级还是TB级?url_id和word_id的layout是怎样的?是unique还是有大量的重复? 3.请给出硬件配置,CPU/内存/存储/操作系统 另外,好慢是多慢?请给出单个select和select ... where word_id in...的运行速度,这样才能有一个baseline用来比较. 在关键信息不足的情况下,开脑洞给出的建议: 1.不要使用select * from,直接指定要用的column。这是个常识。 2.没有主键的表word_id的index不会发生作用,mysql还是会做table scan的。但是,如果url_id有大量的重复,索引的效率会非常低,建议建立一个新的column,类型是int auto_increment primary key。这样虽然会多占一些空间,但是能让word_id的index有效地发生作用。 3.利用mysql自己的partition功能,把每一个partition放到不同的物理硬盘上,查询的时候并行处理,速度还可以快若干倍。 4.如果我的猜测成立,这个表的数据量不会太大(GB级),可以考虑用mysql的memory table全部放在内存里。 另外,在应用的角度也可能有很大的优化空间。从sql语句来看,你试图返回包含指定的关键字的所有记录。问题是,包含某个关键字的记录可能成千上万。例如:一个关键字出现在100万个网页中,平均每个网页出现10次,那么一共会返回1000万条记录。但是你很可能并不需要返回这么多记录。你可能只需要返回前100个url id就可以了(知道哪些网页包含了该关键字),那么sql可以写成: ```sql select url_id from table xxx where word_id = yyy order by primaryid limit 100; ``` 如果用户需要下100条,再依次往下取。如果要知道某个关键字在某个网页中的位置信息(word_location),那么再给定url_id去取: ```sql select word_location from table xxx where word_id = yyy and url_id = zzz; ``` 如果你真的需要同时返回1000个关键字在所有的网页中的所有的位置信息,那么我估计你们的需求一定是出问题了。最后,如果我来处理这个问题,这么简单的数据结构,我会直接写点代码,用hash table在内存中处理(如果内存放得下的话)。
    发布于 2022-01-23 07:55 •IP属地 天津
    举报
    评论
    收藏