首页 > 数据库 >mysql 调优-sql 优化

mysql 调优-sql 优化

时间:2023-05-17 16:22:06浏览次数:42  
标签:COUNT join sql 查询 索引 调优 mysql order id

连接查询

原理涉及到 index nested-loop join , block nested-loop join ,join buffer size ,hash join(mysql8)等,感觉没必要记那么多

需要知道会一次性把驱动表的数据加载到内存中(如果 join buffer size 放得下),然后循环每个驱动表去对比被驱动表的数据就好了

  • 保证被驱动表的JOIN字段已经创建了索引
  • 需要 JOIN 的字段,数据类型保持绝对一致,不然会隐式转型会导致索引失效
  • LEFT JOIN 时,选择小表作为驱动表, 大表作为被驱动表 。减少外层循环的次数
  • INNER JOIN 时,MySQL会自动将 小结果集的表选为驱动表 。选择相信MySQL优化策略
  • 能够直接多表关联的尽量直接关联,不用子查询。(减少查询的趟数)
  • 不建议使用子查询,建议将子查询SQL拆开结合程序多次查询,或使用 JOIN 来代替子查询

子查询

能不使用就不使用,可以想办法使用连接查询替换子查询

  • 如果需要会产生临时表,临时表的创建和销毁需要额外的资源
  • 临时表的结果集不会有索引
  • 子查询结果集越大,性能就越差

order by

order by 的 explain Extrl 中会有两种情况,一种是使用索引 index,一种是 FileSort

FileSort 不能使用索引,所以只能把数据加载到内存中排序,如果结果集过多,只能放到磁盘进行IO来排序

  • 当数据量过大哪怕 order by 的列有索引,也可能不会走索引
    • 前提是查的列和order by 的列不同和没有(意味着不能索引覆盖,每个 select 的别的字段都需要回表)
    • 当数据量很大,就算有索引,也要每条数据都回表,这个代价也很大,优化器可能就会直接不适用该索引,把所有的数据都放进内存
  • order by 多个字段
    • 因为索引是有顺序的,如果要降序,所有的字段都要降序才会走索引。不能一些升序一些降序

分页

  • 比如 limit 200000, 10。mysql 会查询 200010 条数据丢弃前 200000,只要最后10条

    -- 优化思路1(id不自增)
    select * from t_user t1 
    	inner join (select id from t_user order by id limit 200000, 10) t2
    	on t1.id = t2.id
    	
    -- 优化思路2(id自增,且步长为1)
    select * from t_user where id > 200000 limit 10
    
    -- 注意上面两种方式 EXPLAIN 的 orws 会很大,如果把范围定死能解决
    ... where id > ... and id < ...
    

索引覆盖和下推

mysql 调优-利用索引覆盖和下推

其他优化

  • EXISTS 和 IN(遵循小表驱动大表原则)
    • 驱动表是小表,就用 EXISTS;驱动表是大表就用 IN
  • COUNT(前提是 Mysql 和 没有 null 字段)
    • 如果是 MyISAM ,复杂度是 O(1)
    • 如果是 InnoDB,复杂度是O(N)
    • COUNT(1) 和 COUNT(*) 差不多
    • COUNT(列),不要用ID,因为是聚簇索引占用空间比较多,会大于COUNT(二级索引列)。即使用 COUNT(1),MySQL 也会找一列占用空间小的二级索引列来统计
  • SELECT *
    • 把 * 会转化成具体的字段,到系统表中查这个表有哪些字段
    • 不能使用覆盖索引
  • LIMIT 1
    • 首先 LIMIT 会全表扫描,如果有了 limit 1,就不会全表了,找到一条就OK
    • 如果 where 列有唯一索引,就可以不需要 limit 1 了

标签:COUNT,join,sql,查询,索引,调优,mysql,order,id
From: https://www.cnblogs.com/hangychn/p/17409158.html

相关文章

  • mysql 调优-索引失效
    范围条件放最后面,不管单列还是多列索引,把能过滤最多的索引放前面用不用索引最终都是优化器决定的,EXPLAINjson格式里的执行成本决定最左匹配,如果是联合索引,查找索引树的时候,只能根据第一个索引才能找到第二个第三个,如果顺序没对就不会走索引--联合索引(name,code,ad......
  • [MySQL事务一文搞懂]
    [MySQL事务一文搞懂]1、什么是事务?事务(Transaction),顾名思义就是要做的或所做的事情,数据库事务指的则是作为单个逻辑工作单元执行的一系列操作(SQL语句)。这些操作要么全部执行,要么全部不执行。2、为什么需要事务把一系列sql放入一个事务中有两个目的:为数据库操作提供了一个......
  • MySQL回表 索引覆盖02
    资料来源:  https://zhuanlan.zhihu.com/p/401198674?utm_id=0  ......
  • mysql 调优-利用索引覆盖和下推
    回表只查询一次索引得不到想要的数据,典型的场景就是非聚簇索引查询:先拿到主键ID,再根据id查询一次得到数据(再次查询这就是回表)索引覆盖:根据普通索引查询不回表就能得到数据--联合索引(age,addr)selectage,addrfromt_userwhereage>10;--单列索引(不一定非要联合索引......
  • mysql 事务与隔离级别
    ACIDAtomicity:原子性(UNDOLOG实现),一组操作要么都成功,要么都失败Consistency:一致性(UNDOLOG实现),从一个合法状态变为另一个合法状态(语义上不是语法上)。比如转账之后余额为负数,虽然也能守恒,但是明显不合法。或者转账时A账户钱少了,B账户钱没多,也是不合法的Isolation:隔离性(锁机制实......
  • mysql 锁机制
    表锁:InnoDB支持行锁,不代表着就不支持表锁表锁的S和X锁,MyISAM的锁(不建议在InnoDB中使用)--查看当前有表锁的表showopentableswherein_use>0;--给表加S锁(所有事务都能读,所有事务都不能写)locktablestable_nameread;--给表加X锁(拿到锁的事务可写可读......
  • mysql 底层数据存储结构
    内存和磁盘每次交互都是完整的页,数据页里面存放的是行(不仅仅是数据库的数据行,还有行格式等)页(16k,计算机与内存的最小单位)的上层单位还有区(一个区存放64个页,64*16k=1024k,刚好1M),区上面是段(一个或多个区组成),段上面是表空间(一个或多个段组成)行格式showtablestatuslike't_u......
  • docker 部署nacos单机版并配置mysql支持
    1.配置mysql数据库选用mysql5.7表名为nacos_config,附上建表SQLSETNAMESutf8mb4;SETFOREIGN_KEY_CHECKS=0;--------------------------------Tablestructureforconfig_info------------------------------DROPTABLEIFEXISTS`config_info`;CREATETABLE......
  • springboot中使用application.properties配置mysql和sqlserver
    1.使用依赖*mysql:<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency>*sqlserver:<dependency><groupId>com.microsoft.sqlserver</groupId><art......
  • mysql 存储引擎和索引
    存储引擎引擎特性文件InnoDB默认,支持事务,支持外键,支持行锁和表锁.frm文件存储表结构.ibd文件存储数据和索引MyISAM不支持事务,不支持外键,只支持表锁不支持行锁专门维护了一个常量保存每个表的总记录数(count很快)MyISAM强调的是性能,所以性能上优于InnoDB,但安全......