찾다

Mysql优化相关总结

Jun 07, 2016 pm 02:49 PM
mysql최적화엔진요약관련된선택하다주문하다

优化顺序: 选择适当的引擎和表结构和数据类型 建立索引,优化sql。 增加缓存,redis、memcache。 主从、主主,读写分离。 mysql自带分区表 根据业务耦合垂直拆分,分布式数据库 水平拆分,选择合理的sharding key。 引擎区别与选择: Innodb采用聚簇索引,聚

优化顺序:
  • 选择适当的引擎和表结构和数据类型
  • 建立索引,优化sql。
  • 增加缓存,redis、memcache。
  • 主从、主主,读写分离。
  • mysql自带分区表
  • 根据业务耦合垂直拆分,分布式数据库
  • 水平拆分,选择合理的sharding key。

引擎区别与选择:
  • Innodb采用聚簇索引,聚簇索引包含data。辅助索引(复合索引、前缀索引、唯一索引)存储的是主索引的值,所以查找时需要两次B-Tree搜索,读的效率稍低。但是覆盖索引和自适应的哈希索引可以一定程度上缓解这个问题(自适应哈希索引不需要用户指定,Innodb在运行时动态的根据距离的访问频率和模式为一部分页建立哈希索引,但只存在内存中,停库会丢失,重启后慢慢重新维护)。Innodb使用的是行锁,粒度更小,并发更强。并且读写之间是可以并发的,读不需要加锁,根据隔离级别不同,遇到锁时读取快照。所以读写并发是很好的。另外,Innodb相比MyIsam提供事务和外键功能。
  • MyIsam数据和索引是分开存储的,索引缓存在内存中,索引存储的是数据的磁盘地址。所以不需要多次查询B-Tree,读的性能好。但是MyIsam是表锁,只有读读之间是并发的,因此写的效率差。并且写优先级高,大量写可能导致操作饿死。
  • 综上所述:如果应用的读写操作比例非常大,或需要全文索引,那么可以使用MyIsam(5.6开始Innodb也支持全文索引)。其他情况,除了特殊情况特殊分析,推荐Innodb。

数据类型的选择:
  • char、varchar:char是固定长度的,varchar是可变长度的,所以char的处理速度要快得多。char适合长度变化不大的数据列,或要求查询速度很严苛的场景。Myisam建议用char,Innodb建议用varchar。
  • text、blob:blob可以存二进制,text只能存字符数据。可以通过合成索引来提高大文本字段的检索性能(建立一个额外的列存储大文本列数据的散列值),但这种方法只适用于精确完整的匹配查询。前缀索引也有助于查询,但查询条件不能以%开头。
  • 浮点数、定点数:float、double是浮点数,精度超出时会四舍五入。decimal、numberic是定点数,实际使用字符串存储的,所以精度更高,超出精度会警告或直接报错。所以:货币等精度敏感的数据要用定点数,因为浮点数存在误差问题。
  • 日期类型:DATETIME能存储年月日时分秒,比TIMESTAMP能表示的年份更久远。如果涉及时区问题,用TIMESTAMP。

字符集: 
  • 不同的字符集可能涉及隐式的转换,而导致索引失效。

表结构:
  • 选择合适的主键(选择性,长短),不要宽表,不要太多关联,不要大字段。
  • 关于范式:
    • 第一,一个字段只存一个意义的值。{学号,性别+年龄} 。解决办法:{学号,性别,年龄}
    • 第二,如果主键是复合主键,非主键字段不能依赖主键的一部分,必须依赖全部。{学号,学科,分数,总分},分数依赖复合主键,但是总分只依赖学科一个字段,所以不符合第二范式。解决办法:{学号,学科,分数} {学科,总分}
    • 第三,不能有冗余。{学号,班级,班主任}班主任字段就会有大量冗余。解决办法:({学号,班级} {班级,班主任})
    • 范式不一定要严格遵守,要根据具体情况抉择,适当的违反有时候会带来好处更多一些。例如,
  • qq的用户表存储qq图标的点亮情况,如果每个图标用一个字段存储,那么几十个图标会使表很宽、很浪费空间。如果用位图存储所有的点亮情况,一个或者两个字段就可以。虽然违反了第一范式,但是依然是个好办法。
  • 第二、第三范式虽然保证了表的严谨,但是可能带来更多的连接。适当违反可以减少连接,特别是当分布式部署时,会省去很多麻烦。

索引的设计和使用:
  • Myisam和Innodb的索引都是BTree索引,B代表平衡树。都支持前缀索引,前缀索引有个缺点:order by和group by不能使用该索引。Myisam支持全文索引(5.6开始innodb也支持全文索引)。
  • 最适合做索引的列是出现在where子句和链接子句中的列,而不是select中的。
  • 索引列要使用短列,如果长字符列做索引,尽量用前缀索引,在最短的长度内,满足足够的选择性。
  • 不要过度索引,给插入和更新带来很大负担。
  • Innodb尽量用自增列做主索引,如果不能,也不要用大字段。
  • 最左前缀原则是BTree索引使用的首要原则,即索引条件中列的顺序,按复合索引中列的顺序,从左到右尽量覆盖,中间不能间断,且尽量以精确的“=”为条件。从左到右第一个使用范围比较的条件可以使用索引,但后面的条件列不再能使用索引。
  • 常见不能使用索引的场景:
    • 以%开头的Like查询。可以考虑用全文索引。或利用Innodb的聚簇索引,扫索引比扫表快得多。例如:一个表有主键id,辅助索引name。现在想根据name模糊搜索 name like %end%,直接select * from table where name like %end%,会引起表的全扫描,效率低下。因为Innodb每个辅助索引中存的都是主键的值,所以可以改为select * from (select id from table where name like %end%) a, table b where a.id = b.id;  这样子查询中因为id和name在辅助索引中满足了覆盖索引,只扫索引就可以拿到所有满足条件的id,然后根据id再去查询最终结果。
    • 出现类型转换、函数、运算、转码时。
    • 不包含复合索引左侧列。
    • mysql猜测扫表比使用索引快的时候
    • or连接的条件中,每个字段必须都能用到索引,否则将全不使用索引。

事务和锁:
  • Innodb提供事务功能,Myisam不提供。
  • Innodb采用行级锁,也支持表级锁。Myisam提供表级锁。Innodb的读写并发性更好,但行级锁有出现死锁的可能。
  • Innodb的行级锁是对索引项加锁实现的,意味着不通过索引检索就会锁定所有记录,与表锁相同。行锁分为三种:
    • record lock:索引项加锁
    • gap lock:间隙锁
    • Next-key lock:前面两个的组合
  • 事务:
    • 原子性、一致性、持久性、隔离性
    • 并发事务处理能提高效率和资源利用率,但是也带来了问题:
      • 更新丢失
      • 脏读
      • 不可重复读
      • 幻读
    • 隔离级别:脏读、不可重复读、幻读都是一致性问题,需要隔离机制来解决。隔离机制有两种:加锁、生成一致性快照。事务隔离越严格,副作用越小,代价越大。现有4个隔离级别,可以根据业务不同进行选择:
      • 未提交读 read uncommit
      • 已提交读 read commit : 解决脏读
      • 可重复读 repeatable read : 解决不可重复读 (默认级别)
      • 可序列化 serializable : 解决幻读
    • 默认的隔离界别可重复读,会出现幻读的问题。select...for update可以解决幻读问题。eg:select * from data where id
  • 死锁预防:
    • 以相同顺序访问表
    • 事务中,如果需要更新记录,应该直接申请足够级别的锁:排它锁。

  • 分布式事务:5.0.3开始支持,且只有Innodb。两段式提交,但是效率不理想。

表的拆分:
  • 垂直拆分:主码和一部分列放在一个表, 主码和另一部分放在另外一个表。好处是行更小,数据页能放更多缓存,坏处是需要管理冗余,获取全部数据需要join。
  • 水平拆分:当表很大或表中数据本来就具有独立性时。优点:降低索引层数,缺点:给应用带来复杂性。

分区表:
  • 把一个表分成多个小的部分,对应用来说是透明的。可以存储更多的数据,提高查询吞吐量。where字句包含分区条件时,可以只扫描部分分区,提高效率。sum、count等操作,可以在分区上并行进行再汇总。
  • 同一个表的所有分区必须相同引擎。
  • 分区类型:RANGE 范围,LIST 根据枚举,HASH 散列,KEY 类似hash。不能使用主键、唯一键以外的字段做分区字段。

优化手段:
  • 通过慢查询日志查看已经执行的慢语句记录。show processlist查看当前mysql正在运行的线程。
  • EXPLAIN查看慢sql的执行计划。
    • select_type:select的类型。SIMPLE 简单表、PRIMARY 主查询、UNION 联合中第二个或后面的、SUBQUERY子查询。
    • table:表名
    • type:在表中找到所需行的方式。效率从低到高:
      • ALL:全表扫描
      • index:索引全扫描
      • range:索引范围扫描
      • ref:使用非唯一索引或唯一索引的前缀索引
      • eq-ref:使用唯一索引
      • const   system : 单表只有最多一个匹配行,可以非常迅速的找到。
      • NULL:不需要访问表或者索引。
    • possible_keys:可能使用的索引
    • keys:实际使用的索引
    • key_len:使用到的索引字段的长度
    • rows:扫描行的数量
    • Extra:额外的信息
  • explain extended 加上show warnings能够看到sql真正执行前,优化器做了哪些修改。
  • show profiles可以查看当前线程每个查询。show profile for query + id(show profiles得到的),可以看每一步的耗时。还可以进一步在cpu io block等级别查看在使用什么资源时,耗时高。例如:show profile cpu for query + id。
  • 5.6提供了trace对sql进行跟踪,进一步了解优化器选择最终执行计划的原因。
    • 首先打开trace:set optimizer_trace="enabled=on",END_MARKERS_IN_JSON=on;
    • 缓存大小:set  optimizer_trace_max_mem_size=1000000;
    • 执行sql
    • select * from information_schema.optimizer_trace; 查看跟踪文件。

sql语句优化:
  • insert:如果单个客户端插入多条,尽量insert into test values(1,2),(3,4),(5,6)如此同时插入,减少交互
  • order by:btree索引是有序存储的,可以利用。所以尽量减少额外的filesort,通过索引直接返回有序数据。做法:order by与where使用相同的索引、复合索引。并且order by的字段都是升序或都是降序。 如果做不到,排序操作很多,数据较多时,适当开大sort_buffer_size让排序尽量在内存中完成,这个值是每个线程独占的,多个线程就多个buffer,注意!
  • group by:默认情况下group by c1, c2会对c1,c2...的所有字段排序,如果不需要刻意通过显示的加一个order by null禁止排序,提高效率。
  • 嵌套查询:有些情况可以使用连接代替。
  • or:保证每个列都能用到索引,会发现mysql处理时,将每个字段分别查询后进行了UNION操作。
  • 分页查询:limit1000,10 会排序出前1010行,最后只去10行。效率低。
    • 利用覆盖索引:子查询先利用覆盖索引查询到满足条件的主键,再利用主键回表查找记录。eg:select name, value from data order by name limit 1000, 10; 改为 select name, value from data a inner join (select id from data order by name limit 1000, 10) b on a.id = b.id;
    • 纪录上一次结果的最后一个排序列的值,然后:where name > lastvalue order by name limit 10; 这种方法不适合排序字段有重复值的情况,会丢纪录。
  • SQL提示:
    • USE INDEX : 让mysql参考提供的索引。eg:select * from data use index (idx_id);
    • IGNORE INDEX:忽略某索引
    • FORCE INDEX:强制使用某索引
  • 对大表的统计操作:新建临时表,讲所需数据导入临时表,再统计。好处:隔离,可以临时加字段、索引。
  • in not in  exist  not exist:    
  • 技巧:
    • order by rand() limit 5;随机选出5行。

应用优化:
  • 连接建立的代价较大,应用连接池。
  • 如果表更新操作不频繁,可以利用查询缓存。一旦表发生一点更新,整个表的缓存都将失效。
  • 增加cache层。
  • 主从来分摊读写压力,但是存在延迟,需考虑。
  • 分布式数据库CLUSTER。

其他优化:
  • 定期分析表:analyze table test; 分析表可以使系统得到准确的统计信息,sql能生成更正确的执行计划。
  • 优化表:optimize table test;合并空间碎片。
  • 上述两个操作会锁表!!!

集群:
  • Mysql Cluster :
    •  节点类型:管理节点(1个)、SQL节点(应用和数据节点间的桥梁)、数据节点(存放数据,有多个镜像节点应对宕机)
  • MMM架构:
    • 双主复制架构,只有一个主提供写,另一个提供一部分读。
  • MHA架构:
    • 两部分组成:MHA Manager管理节点、MHA 
성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
산성 특성 (원자력, 일관성, 분리, 내구성)을 설명하십시오.산성 특성 (원자력, 일관성, 분리, 내구성)을 설명하십시오.Apr 16, 2025 am 12:20 AM

산성 속성에는 원자력, 일관성, 분리 및 내구성이 포함되며 데이터베이스 설계의 초석입니다. 1. 원자력은 거래가 완전히 성공적이거나 완전히 실패하도록합니다. 2. 일관성은 거래 전후에 데이터베이스가 일관성을 유지하도록합니다. 3. 격리는 거래가 서로를 방해하지 않도록합니다. 4. 지속성은 거래 제출 후 데이터가 영구적으로 저장되도록합니다.

MySQL : 데이터베이스 관리 시스템 대 프로그래밍 언어MySQL : 데이터베이스 관리 시스템 대 프로그래밍 언어Apr 16, 2025 am 12:19 AM

MySQL은 데이터베이스 관리 시스템 (DBMS) 일뿐 만 아니라 프로그래밍 언어와 밀접한 관련이 있습니다. 1) DBMS로서 MySQL은 데이터를 저장, 구성 및 검색하는 데 사용되며 인덱스 최적화는 쿼리 성능을 향상시킬 수 있습니다. 2) SQL과 같은 ORM 도구를 사용하여 Python에 내장 된 SQL과 프로그래밍 언어를 결합하면 작업을 단순화 할 수 있습니다. 3) 성능 최적화에는 인덱싱, 쿼리, 캐싱, 라이브러리 및 테이블 부서 및 거래 관리가 포함됩니다.

MySQL : SQL 명령으로 데이터 관리MySQL : SQL 명령으로 데이터 관리Apr 16, 2025 am 12:19 AM

MySQL은 SQL 명령을 사용하여 데이터를 관리합니다. 1. 기본 명령에는 선택, 삽입, 업데이트 및 삭제가 포함됩니다. 2. 고급 사용에는 조인, 하위 쿼리 및 집계 함수가 포함됩니다. 3. 일반적인 오류에는 구문, 논리 및 성능 문제가 포함됩니다. 4. 최적화 팁에는 인덱스 사용, 선택*을 피하고 한계 사용이 포함됩니다.

MySQL의 목적 : 데이터를 효과적으로 저장하고 관리합니다MySQL의 목적 : 데이터를 효과적으로 저장하고 관리합니다Apr 16, 2025 am 12:16 AM

MySQL은 데이터 저장 및 관리에 적합한 효율적인 관계형 데이터베이스 관리 시스템입니다. 장점에는 고성능 쿼리, 유연한 트랜잭션 처리 및 풍부한 데이터 유형이 포함됩니다. 실제 애플리케이션에서 MySQL은 종종 전자 상거래 플랫폼, 소셜 네트워크 및 컨텐츠 관리 시스템에서 사용되지만 성능 최적화, 데이터 보안 및 확장성에주의를 기울여야합니다.

SQL 및 MySQL : 관계 이해SQL 및 MySQL : 관계 이해Apr 16, 2025 am 12:14 AM

SQL과 MySQL의 관계는 표준 언어와 특정 구현의 관계입니다. 1.SQL은 관계형 데이터베이스를 관리하고 운영하는 데 사용되는 표준 언어로, 데이터 추가, 삭제, 수정 및 쿼리를 허용합니다. 2.MySQL은 SQL을 운영 언어로 사용하고 효율적인 데이터 저장 및 관리를 제공하는 특정 데이터베이스 관리 시스템입니다.

InnoDB Redo Logs 및 Undo Logs의 역할을 설명하십시오.InnoDB Redo Logs 및 Undo Logs의 역할을 설명하십시오.Apr 15, 2025 am 12:16 AM

InnoDB는 Redologs 및 Undologs를 사용하여 데이터 일관성과 신뢰성을 보장합니다. 1. Redologs는 사고 복구 및 거래 지속성을 보장하기 위해 데이터 페이지 수정을 기록합니다. 2. 결점은 원래 데이터 값을 기록하고 트랜잭션 롤백 및 MVCC를 지원합니다.

설명 출력 (유형, 키, 행, 추가)에서 찾아야 할 주요 메트릭은 무엇입니까?설명 출력 (유형, 키, 행, 추가)에서 찾아야 할 주요 메트릭은 무엇입니까?Apr 15, 2025 am 12:15 AM

설명 명령에 대한 주요 메트릭에는 유형, 키, 행 및 추가가 포함됩니다. 1) 유형은 쿼리의 액세스 유형을 반영합니다. 값이 높을수록 Const와 같은 효율이 높아집니다. 2) 키는 사용 된 인덱스를 표시하고 NULL은 인덱스가 없음을 나타냅니다. 3) 행은 스캔 한 행의 수를 추정하여 쿼리 성능에 영향을 미칩니다. 4) Extra는 최적화해야한다는 Filesort 프롬프트 사용과 같은 추가 정보를 제공합니다.

설명에서 임시 상태를 사용하고 피하는 방법은 무엇입니까?설명에서 임시 상태를 사용하고 피하는 방법은 무엇입니까?Apr 15, 2025 am 12:14 AM

Temporary를 사용하면 MySQL 쿼리에 임시 테이블을 생성해야 할 필요성이 있으며, 이는 별개의, 그룹 비 또는 비 인덱스 열을 사용하여 순서대로 발견됩니다. 인덱스 발생을 피하고 쿼리를 다시 작성하고 쿼리 성능을 향상시킬 수 있습니다. 구체적으로, 설명 출력에 사용되는 경우, MySQL은 쿼리를 처리하기 위해 임시 테이블을 만들어야 함을 의미합니다. 이것은 일반적으로 다음과 같은 경우에 발생합니다. 1) 별개 또는 그룹을 사용할 때 중복 제거 또는 그룹화; 2) OrderBy가 비 인덱스 열이 포함되어있을 때 정렬하십시오. 3) 복잡한 하위 쿼리 또는 조인 작업을 사용하십시오. 최적화 방법은 다음과 같습니다. 1) Orderby 및 GroupB

See all articles

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
4 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
4 몇 주 전By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
1 몇 달 전By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 채팅 명령 및 사용 방법
1 몇 달 전By尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

맨티스BT

맨티스BT

Mantis는 제품 결함 추적을 돕기 위해 설계된 배포하기 쉬운 웹 기반 결함 추적 도구입니다. PHP, MySQL 및 웹 서버가 필요합니다. 데모 및 호스팅 서비스를 확인해 보세요.

Eclipse용 SAP NetWeaver 서버 어댑터

Eclipse용 SAP NetWeaver 서버 어댑터

Eclipse를 SAP NetWeaver 애플리케이션 서버와 통합합니다.

VSCode Windows 64비트 다운로드

VSCode Windows 64비트 다운로드

Microsoft에서 출시한 강력한 무료 IDE 편집기

SublimeText3 영어 버전

SublimeText3 영어 버전

권장 사항: Win 버전, 코드 프롬프트 지원!

ZendStudio 13.5.1 맥

ZendStudio 13.5.1 맥

강력한 PHP 통합 개발 환경