搜尋
首頁資料庫mysql教程Mysql优化相关总结

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
MySQL:世界上最受歡迎的數據庫的簡介MySQL:世界上最受歡迎的數據庫的簡介Apr 12, 2025 am 12:18 AM

MySQL是一種開源的關係型數據庫管理系統,主要用於快速、可靠地存儲和檢索數據。其工作原理包括客戶端請求、查詢解析、執行查詢和返回結果。使用示例包括創建表、插入和查詢數據,以及高級功能如JOIN操作。常見錯誤涉及SQL語法、數據類型和權限問題,優化建議包括使用索引、優化查詢和分錶分區。

MySQL的重要性:數據存儲和管理MySQL的重要性:數據存儲和管理Apr 12, 2025 am 12:18 AM

MySQL是一個開源的關係型數據庫管理系統,適用於數據存儲、管理、查詢和安全。 1.它支持多種操作系統,廣泛應用於Web應用等領域。 2.通過客戶端-服務器架構和不同存儲引擎,MySQL高效處理數據。 3.基本用法包括創建數據庫和表,插入、查詢和更新數據。 4.高級用法涉及復雜查詢和存儲過程。 5.常見錯誤可通過EXPLAIN語句調試。 6.性能優化包括合理使用索引和優化查詢語句。

為什麼要使用mysql?利益和優勢為什麼要使用mysql?利益和優勢Apr 12, 2025 am 12:17 AM

選擇MySQL的原因是其性能、可靠性、易用性和社區支持。 1.MySQL提供高效的數據存儲和檢索功能,支持多種數據類型和高級查詢操作。 2.採用客戶端-服務器架構和多種存儲引擎,支持事務和查詢優化。 3.易於使用,支持多種操作系統和編程語言。 4.擁有強大的社區支持,提供豐富的資源和解決方案。

描述InnoDB鎖定機制(共享鎖,獨家鎖,意向鎖,記錄鎖,間隙鎖,下一鍵鎖)。描述InnoDB鎖定機制(共享鎖,獨家鎖,意向鎖,記錄鎖,間隙鎖,下一鍵鎖)。Apr 12, 2025 am 12:16 AM

InnoDB的鎖機制包括共享鎖、排他鎖、意向鎖、記錄鎖、間隙鎖和下一個鍵鎖。 1.共享鎖允許事務讀取數據而不阻止其他事務讀取。 2.排他鎖阻止其他事務讀取和修改數據。 3.意向鎖優化鎖效率。 4.記錄鎖鎖定索引記錄。 5.間隙鎖鎖定索引記錄間隙。 6.下一個鍵鎖是記錄鎖和間隙鎖的組合,確保數據一致性。

MySQL查詢性能差的常見原因是什麼?MySQL查詢性能差的常見原因是什麼?Apr 12, 2025 am 12:11 AM

MySQL查询性能不佳的原因主要包括没有使用索引、查询优化器选择错误的执行计划、表设计不合理、数据量过大和锁竞争。1.没有索引导致查询缓慢,添加索引后可显著提升性能。2.使用EXPLAIN命令可以分析查询计划,找出优化器错误。3.重构表结构和优化JOIN条件可改善表设计问题。4.数据量大时,采用分区和分表策略。5.高并发环境下,优化事务和锁策略可减少锁竞争。

您什麼時候應該使用複合索引與多個單列索引?您什麼時候應該使用複合索引與多個單列索引?Apr 11, 2025 am 12:06 AM

在數據庫優化中,應根據查詢需求選擇索引策略:1.當查詢涉及多個列且條件順序固定時,使用複合索引;2.當查詢涉及多個列但條件順序不固定時,使用多個單列索引。複合索引適用於優化多列查詢,單列索引則適合單列查詢。

如何識別和優化MySQL中的慢速查詢? (慢查詢日誌,performance_schema)如何識別和優化MySQL中的慢速查詢? (慢查詢日誌,performance_schema)Apr 10, 2025 am 09:36 AM

要優化MySQL慢查詢,需使用slowquerylog和performance_schema:1.啟用slowquerylog並設置閾值,記錄慢查詢;2.利用performance_schema分析查詢執行細節,找出性能瓶頸並優化。

MySQL和SQL:開發人員的基本技能MySQL和SQL:開發人員的基本技能Apr 10, 2025 am 09:30 AM

MySQL和SQL是開發者必備技能。 1.MySQL是開源的關係型數據庫管理系統,SQL是用於管理和操作數據庫的標準語言。 2.MySQL通過高效的數據存儲和檢索功能支持多種存儲引擎,SQL通過簡單語句完成複雜數據操作。 3.使用示例包括基本查詢和高級查詢,如按條件過濾和排序。 4.常見錯誤包括語法錯誤和性能問題,可通過檢查SQL語句和使用EXPLAIN命令優化。 5.性能優化技巧包括使用索引、避免全表掃描、優化JOIN操作和提升代碼可讀性。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
4 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器