mysql什么分表?以及我什么知道该去哪个表取数据?
@老虎会游泳,只是计时的话,不懂该如何优化呀
(但好像一股脑分表可以很好地缓解?)
@无名啊,在SQL语句前面加explain可以显示MySQL准备如何进行查询。
@老虎会游泳,就@大尨 的B表而言,应该都是走这种步骤吧
(uid, type, wxid) 得到 id,根据 id 得到 ctime, extend 等
@无名啊,但是这样的简单三条件搜索,已经没有必要explain了,如果存在索引index(uid, type, wxid)肯定就查询索引啊,还能怎么样呢?所以还嫌慢的话,缩小表的规模(分表)是唯一选择。
index(uid, type, wxid)
Db::table('ulogs')->where('uid',1)->where('type',1)->where('wxid',$wxid)->first();
@无名啊,顺便一提,分表也会加快插入,因为更新大索引比更新小索引慢很多。而更新索引时可能需要全表加锁,进而影响查询。
@无名啊,一个查询大概会随机读几次硬盘,作为MySQL用户,我们不需要知道这些。就算知道了它读写几次,如果不缩小表的规模,我们也没有办法让索引index(uid, type, wxid)的查询和更新变得更快。但是缩小表的规模肯定可以变快,这是经过实践广泛验证的。
一个查询大概会随机读几次硬盘
@老虎会游泳,我是在想,独立wxid, appid,会不会单表三层B+树所允许的最大记录数可以嗖嗖嗖地提升
wxid
appid
如果wxid和appid独立数量不多的话,说不定还能缓存在内存里
@无名啊,只有一种情况我们可以优化,就是@大尨 没有创建索引index(uid, type, wxid)。如果确实没有创建,那么创建一个应该可以大幅度提升查询性能(但是相对的,可能会降低插入性能,因为插入现在需要更新索引)。
@无名啊,在服务器为MySQL查询缓存分配的内存足够多的情况下,索引当然会在内存里,但在内存里搜索的速度也会随着条目的增长而逐渐变慢。 无论如何设计表结构,我们都需要进行uid, type, wxid三字段联合搜索,我认为目前的表结构已经是最优的形式了。
uid, type, wxid
@老虎会游泳,独立wxid和appid成单独的表,有帮助吗?
@老虎会游泳,独立后,B表的索引由
uid, type, wxid(约26字节?假设wxid长20字节)
变成
uid, type, wxid_id(约10字节?)
uid, type, wxid_id
行数据也可减少36字节(假设appid也长20字节)
@无名啊,请用容易理解的形式描述表结构,比如表名(字段1, 字段2, 字段3)。从51楼得不到任何有效的表结构。
表名(字段1, 字段2, 字段3)
@老虎会游泳,B表由
id, uid, type, crc, wxid, appid, extend, ctime
id, uid, type, crc, wxid_id, appid_id, extend, ctime
@老虎会游泳,增加wxid(id INT PRIMARY KEY, wxid VARCHAR(32))和appid(id, appid)表
wxid(id INT PRIMARY KEY, wxid VARCHAR(32))
appid(id, appid)
@无名啊,对于大规模数据,我不认为整数索引会比字符串索引快多少。而且你要考虑到,现在插入B表将变成先查询C表,如果不存在,再插入C表;再查询D表,如果不存在,插入D表;从C表和D表获取两个id之后,才能查询或插入B表。我们在B表中节省的时间可能完全损耗在了对C表和D表的操作上。具体如何你可以实验验证。
@老虎会游泳,
对于大规模数据,我不认为整数索引会比字符串索引快多少
我的目的是增大单表3层B+树时的最大容量
先查询C表,如果不存在,再插入C表……节省的时间可能损耗在了对C表的操作上
这个步骤,应该在插入A表时,已经做了吧
先查询C/D表,如果不存在,再插入C/D表
有INSERT OR IGNORE INTO ... RETURNING id这种语句吧好像,可以简化成一条插入语句
INSERT OR IGNORE INTO ... RETURNING id
@无名啊,而且你要考虑到,对于索引index(uid, type, wxid)来说,uid和type都是整数类型。对于相同的uid和type来说,对应的wxid应该是极其有限的。所以就算wxid使用完整字符串长度作为索引,也不会对性能产生什么严重的影响,因为uid, type组合已经把搜索范围缩小到了个位数。
uid, type
@无名啊,INSERT OR IGNORE INTO ... RETURNING id确实很好用,但它只优化了应用程序和MySQL之间的I/O,MySQL查询引擎所需要做的操作和先SELECT再INSERT没有区别。
@老虎会游泳,只是计时的话,不懂该如何优化呀
(但好像一股脑分表可以很好地缓解?)