0%

查询速度慢的原因

  1. 生命周期太长:从客户端到服务端,然后在服务端进行解析、生成执行计划、执行(包括数据的分组聚合处理等)、并返回结果
  2. 资源消耗:网络资源、CPU资源、锁等待、IO资源
  3. 访问的数据太多,大多数是行数据,也包括列数据
    • 是否向数据库请求了不需要的数据
      • 查询不需要的数据,比如LIMIT 1000000,10
      • 是否返回了全部列,比如select * from
      • 重复查询相同的数据,可以使用缓存解决
    • MySQL是否在扫描额外的记录,可以使用explain分析,关注以下三个指标
      • 响应时间
        • 服务时间:数据库处理这个查询实际消耗的时间
        • 排队时间:等待时间,比如IO操作、锁等待等
      • 扫描的行数
        • 通过explain中的type列获取访问类型(全表扫描、范围扫描、唯一索引查询、常数引用等)
        • 使用where条件的方式
          • 在索引中使用where过滤数据,存储引擎层完成
          • 索引覆盖扫描(Extra中出现Using index),服务层直接在索引中处理,不需要回表
          • 冲数据表中返回数据(Extra中出现Using index),服务层完成(先从数据库中获取数据,然后在过滤数据)
      • 返回的行数
        • 优化技巧(扫描比返回的数据多)
          • 使用索引覆盖扫描
          • 修改表结构
          • 重新SQL
阅读全文 »

排序算法

sort_buffer_size

sort_buffer_size的特点

  1. 每个线程都会分配一个固定的大小,作为排序的buffer
  2. 默认256KB,线程独有
  3. 使用场景:排序比较大,且内存充足、并发不大时,可以适当增加该值,如果太大会耗尽内存(例如:500个连接将会消耗 500*sort_buffer_size(8M)=4G内存)
  4. connection级别的参数,在每个connection(session)第一次需要使用这个buffer的时候,一次性分配设置的内存
  5. 内存分配方式:超过2KB的时候,就会使用mmap() 而不是 malloc() 来进行内存分配,导致效率降低
  6. 调优检查:explain select*from table where order limit;出现filesort(外部排序)
阅读全文 »

阻塞队列,关键字是阻塞,先理解阻塞的含义,在阻塞队列中,线程阻塞有这样的两种情况:
 当队列中没有数据的情况下,消费者端的所有线程都会被自动阻塞(挂起),直到有数据放入队列。

阅读全文 »

选择优化的数据类型

  1. 更小的通常更好
  2. 简单就好
  3. 尽量避免使用NULL

数值类型

在mysql中的数值类型主要包括:整数和实数。

  1. 在mysql中可以指定整数类型的宽度,但是该宽度只是用来显示可展示的长度,不能作为限制类型的实际长度
  2. mysql中支持精确类型的实数和非精确类型的实数,需要根据实际场景进行选择,也可以根据业务场景转换成BIGINT进行存储
    具体类型如下表所示:
阅读全文 »

读写锁的改进。

并发度
ReentrantLock 读读互斥、读写互斥、写写互斥
ReentrantReadWriteLock 读读不互斥、读写互斥、写写互斥
StampedLock 读读不互斥、读写不互斥、写写互斥
阅读全文 »

无锁的优点(效率高的原因)

  1. 不会出现上下文切换
  2. 需要额外CPU的支持

CAS特点

结合CAS+volatile可以实现无锁并发。

  1. 场景:线程数少、多核 CPU 的场景下
  2. CAS基于乐观锁实现思路,synchronized基于悲观锁的思路
  3. CAS 体现的是无锁并发、无阻塞并发(竞争不激烈的前提下)
  4. 概念:Compare And Swap/Set,3 个参数 CAS(V,E,N)。V 表示要更新的变量(内存值),E 表示预期值(旧的),N 表示新值。当且仅当 V 值等于 E 值时,才会将 V 的值设为 N,如果 V 值和 E 值不同,则说明已经有其他线程做了更新,则当前线程什么都不做。最后,CAS 返回当前 V 的真实值。
阅读全文 »