各大互联网公司必须遵守的核心不要在数据库中进行计算单表数据量:一年内单表纯INT不超过1000W,包括CHAR不超过500W。单个数据库尽可能少的不超过300~400个表和字段,上限控制在20~50个,可以适当冗余(平衡范式和冗余)。拒绝大SQL、大事务、大批量字节和字段数值类型的应用范围。是的,将字符串转换为数字进行存储。可以加快查询速度,节省空间。例如,使用INT而不是CHAR(15)来存储IP。先使用SET和ENUM...(可能有问题!)避免使用NULL少用TEXT/BLOB,如果必须(超过varchar64k的最大限制)必须拆分成一个单独的表,不包含在数据存量中图像索引。尽量不加索引,最好不超过字段数的20%(比如:不加性别),结合核心SQL优先考虑覆盖索引字符字段,必须建立前缀索引。由于字符串很长,您通常可以索引前几个字符而不是整个值以节省空间并获得更好的性能。不要对索引列进行数学运算和函数运算(会导致无法使用索引=>全表扫描),比如whereid+1=100andid=100-1,效率相差甚远自增列或全局ID作为INNODB的主键尽量不要使用外键(受程序约束),高并发时容易死锁SQL。SQL语句尽量简单,因为一条SQL只能在一个CPU上运行。在高并发的情况下,一条大SQL可能会把整个数据库都堵死。简单SQL缓存命中率更高,减少锁表时间(尤其是MyISAM),使用多个CPU维护事务,DB连接足够短,可以立即使用,用完就关闭。将与事务无关的操作放在事务之外,减少锁资源的占用;在不破坏一致性的前提下,使用多个短事务代替长事务(如:发帖时等待上传图片)尽量少用存储过程,少用触发器,减少使用MySQL函数处理结果(客户端程序负责)尽量少用select*,只取需要的数据列,提供使用覆盖索引的可能,减少临时表的生成,更安全的使用in()代替or,因为or的效率是O(n),in()的效率是O(Logn)。比如:wherea=1ORa=100和whereaIN(1,100)合并索引往往很弱智,所以用union代替or查询多个字段。例如:select*fromtwherea=1ORb=2andselect*fromtwherea=1UNIONselect*fromtwhereb=2尽量避免否定搜索,比如NOT、!=等。avoid%前缀模糊查询,由于使用了B+Tree,前缀模糊无法使用索引,导致全表扫描(后缀模糊速度相对较快)减少COUNT(*),使用COUNT(col),前者资源开销大,尽量少用。MyISAM没有WHERECOUNT()而INNODB有WHERECOUNT()。可以使用计数统计:实时统计可以使用memcache,双向更新,凌晨运行benchmark;非实时统计尽量使用单独的统计表,周期性重新计算LIMIT高效分页:传统方式是select*fromtlimit10000,10,推荐方式是select*fromtwhereid>23423limit10。LIMIT的偏移量越大,它就会越慢。还有一些高效的方法:先拿id来LIMIT偏移量,减少整体数据偏移量;获取需要的id,与原表JOIN;程序获取ID,然后用IN填充它。select*fromtwhereid>=(selectidfromtlimit10000,1)limit10,select*fromtINNERJOIN(selectidfromtlimit10000,10)使用(id),selectidfromtlimit10000,10;select*fromtwhereidin(123,456...)如果不需要对结果去重,使用UNIONALL代替UNION(UNION有去重开销)分解JOIN连接,保证高并发。高并发DB不推荐JOINgroupby超过两个表默认会自动升序排序。如果需要去掉排序,需要指定orderbyNULL比较原则:数字对数字,字符对字符。如果数字列与字符类型比较,则同时转换为双精度;如果将字符列与数值类型进行比较,则将字符列的整列转换为一个值,不使用索引查询。loaddata导入数据比insert快20倍左右(不需要刷新Cache)尽量不要用insert...select(延迟,同步错误)批量更新凌晨操作,避免一些高峰期的SQL命令:explain,showprofile,mysqlsla,mysqldumpslow,showslowlog,showprocesslist,showQUERY_RESPONSE_TIME(Percona)约定不同时期使用不同的数据库:real库用于实时数据,sim库用于模拟环境,qa库用于测试,dev开发库。INidin的子查询,一般可以改写为JOIN)程序上不要加锁数据库,因为外部锁对数据库是不可控的,在并发高的时候是灾难,极难加锁debug和troubleshoot(可以使用事务解决)统一字符集:UTF-8,校对规则:utf8_general_ci库名和表名统一小写(区分大小写,不同操作系统有不同限制);字段名称不区分大小写;索引名称默认为idx_field名称;库名要简写,尽量2~7个字母;避免使用保留字命名
