{eval=Array;=+count(Array);}
当一张表的数据量达到千万级别的时候,任何对表的操作都得小心翼翼。核心点在于避免全表扫描、避免锁表、避免产生大量行锁。
本质上是让每一次sql的执行都更快的完成,避免过长时间占用数据库连接,让连接能够迅速的释放回数据库连接池,提供更多稳定的服务。
一旦产生大量的行锁甚至表锁,将会带来连接瞬间被打满、数据库资源耗尽、服务宕机的灾难性后果。所以如何避免以上问题的发生才是最重要的,绝不能等问题发生之后再去解决。
SQL查询的执行路径:
所有sql必须命中索引,禁止全表扫描
禁止like查询,会导致全表扫描
where条件必须符合最左前缀查询原则,会无法命中索引,全表扫描
禁止使用!=、<>、OR等操作符,会导致全表扫描
禁止参与列运算例如:sum、date_format,会导致全表扫描
禁止使用is null、is not null等空判断,会导致全表扫描
禁止使用select *,应该明确指定要查询的列,避免大批量数据传输、磁盘读写
用exist代替in
禁止大表连接查询
避免大字段和核心数据存储在一张表,可以考虑将大字段拆出来存储到OSS、ES、openSearch等数据源中,通过主键关联的形式查询。
主从配置可以支持更多的数据连接,避免了单机连接不足的问题,读写分离可以让读业务走从库,不同的业务走不同的数据库,比如报表业务。
分区分表基本上就是终极方案了,水太深,这里不细说了。
以上,纯属扯淡!回到题主的问题,简单粗暴的方案是啥?数据库内存加大!128G、256G上!硬盘采用SSD!一主多从、读写分离,借助ucloud云RDS轻松完成,有钱就可以了,分区分表?那就不叫简单粗暴了!几千万数据?so easy!
大家有什么好的简单粗暴的方案?欢迎评论区交流讨论~
千万级大表在不考虑分库分表的情况下有如下几个可以优化的地方,仅供参考:
主键最好是递增的,不要用uuid,降低空间占用;
根据需要查询的字段,建立合适的索引(包括联合索引),必要的时候根据explain查看执行计划分析索引是否被命中
根据查询条件,删掉一些命中率比较低的索引,提高数据插入效率;
对于一些复杂查询,比如order by、group by等,要注意执行计划的Extra列是否有Using temporary字样,如果有的话就意味着使用了临时表,这种查询的频率比较高的话,可以适当增大内存临时表空间,可以提高查询速度;
对于这种大数据量的表,查询语句不要使用自动生成的那种,尽量手写SQL,提高执行效率并且避免一些无用字段的查询,尽可能的去使用索引。下面是几句写SQL常用口诀:
全值匹配我最爱,最左前缀要遵守;
带头大哥不能死,中间兄弟不能断;
索引列上不计算,范围之后全失效;
莱克百分写最左,覆盖索引不写星;
不等空值还有噢,索引失效要少用。
如果说你们的查询比较频繁,并且比较复杂,掺杂了大量的模糊查询以及统计查询,建议把数据同步放到 es(Elasticsearch)里面一份,这样问题就解决了。
以上仅供参考,欢迎大家在评论区留言沟通交流!
0
回答0
回答0
回答0
回答0
回答0
回答0
回答0
回答0
回答1
回答