1、对索引列运算,运算包括(+、-、*、/、!、<>、%、like'%_'(%放在前面) 2、类型错误,如字段类型为varchar,where条件用number。 3、对索引应用内部函数,这种情况下应该建立基于函数的索引 如select * from template t where ROUND(t.logicdb_id) = 1 此时应该建ROUND(t.logicdb_id)为索引,mysql8.0开始支持函数索引,5.7可以通过虚拟列的方式来支持,之前只能新建一个ROUND(t.logicdb_id)列然后去维护 4、如果条件有or,即使其中有条件带索引也不会使用(这也是为什么建议少使用or的原因),如果想使用or,又想索引有效,只能将or条件中的每个列加上索引 5、如果列类型是字符串,那一定要在条件中数据使用引号,否则不使用索引; 6、B-tree索引 is null不会走,is not null会走,位图索引 is null,is not null 都会走 7、组合索引遵循最左原则
常用的但容易忘的: 1、如果有主键或者唯一键冲突则不插入:insert ignore into 2、如果有主键或者唯一键冲突则更新,注意这个会影响自增的增量:INSERT INTO room_remarks(room_id,room_remarks) VALUE(1,"sdf") ON DUPLICATE KEY UPDATE room_remarks="234" 3、如果有就用新的替代,values如果不包含自增列,自增列的值会变化:REPLACE INTO room_remarks(room_id,room_remarks) VALUE(1,"sdf") 4、备份表:CREATE TABLE user_info SELECT * FROM user_info 5、复制表结构:CREATE TABLE user_v2 LIKE user6、从查询语句中导入:INSERT INTO user_v2 SELECT * FROM user或者INSERT INTO user_v2(id,num) SELECT id,num FROM user 7、连表更新:UPDATE user a, room b SET a.num=a.num+1 WHERE a.room_id=b.id 8、连表删除:DELETE user FROM user,black WHERE user.id=black.id 锁相关(作为了解,很少用) 1、共享锁: select id from tb_test where id = 1 lock in share mode; 2、排它锁: select id from tb_test where id = 1 for update 优化时用到: 1、强制使用某个索引: select * from table force index(idx_user) limit 2; 2、禁止使用某个索引:select * from table ignore index(idx_user) limit 2; 3、禁用缓存(在测试时去除缓存的影响): select SQL_NO_CACHE from table limit 2; 查看状态 1、查看字符集 SHOW VARIABLES LIKE 'character_set%';2、查看排序规则 SHOW VARIABLES LIKE 'collation%'; SQL编写注意 1、where语句的解析顺序是从右到左,条件尽量放where不要放having2、采用延迟关联(deferred join)技术优化超多分页场景,比如limit 10000,10,延迟关联可以避免回表3、distinct语句非常损耗性能,可以通过group by来优化4、连表尽量不要超过三个表
五、踩坑
1、如果有自增列,truncate语句会把自增列的基数重置为0,有些场景用自增列作为业务上的id需要十分重视2、聚合函数会自动滤空,比如a列的类型是int且全部是NULL,则SUM(a)返回的是NULL而不是03、mysql判断null相等不能用“a=null”,这个结果永远为UnKnown,where和having中,UnKnown永远被视为false,check约束中,UnKnown就会视为true来处理。所以要用“a is null”处理