读高性能MySQL(第4版)笔记12_查询性能优化(下)

这篇具有很好参考价值的文章主要介绍了读高性能MySQL(第4版)笔记12_查询性能优化(下)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

读高性能MySQL(第4版)笔记12_查询性能优化(下)文章来源地址https://www.toymoban.com/news/detail-709977.html

1. “快速、精确和实现简单”

1.1. 三者永远只能满足其二,必须舍掉一个

2. 排序优化

2.1. 无论如何排序都是一个成本很高的操作,所以从性能角度考虑,应尽可能避免排序或者尽可能避免对大量数据进行排序

2.2. 文件排序(filesort)

2.2.1. MySQL需要自己进行排序,如果数据量小则在内存中进行,如果数据量大则需要使用磁盘

2.2.2. 完全是在内存中排序不需要任何磁盘文件时也是如此

2.3. 排序算法

2.3.1. 两次传输排序(旧版本使用)

2.3.1.1. 读取行指针和需要排序的字段,对其进行排序,然后再根据排序结果读取所需要的数据行

2.3.1.2. 即需要从数据表中读取两次数据,第二次读取数据的时候,因为是读取排序列进行排序后的所有记录,这会产生大量的随机I/O,所以两次传输排序的成本非常高

2.3.2. 单次传输排序(新版本使用)

2.3.2.1. 先读取查询所需要的所有列,然后再根据给定列进行排序,最后直接返回排序结果

2.3.2.2. 不再需要从数据表中读取两次数据,对于I/O密集型的应用来说,这样做的效率高了很多

2.3.2.3. 只需要一次顺序I/O就可读取所有的数据,而无须任何的随机I/O

2.4. MySQL在进行文件排序时需要使用的临时存储空间可能会比想象的要大得多

2.5. 如果使用utf8mb4字符集,那么MySQL将会为每个字符预留4字节

2.6. 如果查询中有LIMIT的话,LIMIT也会在文件排序之后应用,所以即使需要返回较少的数据,临时表和需要排序的数据量仍然会非常大

3. 将结果返回给客户端

3.1. 执行查询的最后一个阶段是将结果返回给客户端

3.2. MySQL将结果集返回客户端是一个增量且逐步返回的过程

3.2.1. 服务器端无须存储太多的结果,也就不会因为要返回太多结果而消耗太多内存

4. MySQL查询优化器的局限性

4.1. MySQL查询优化器只对少部分查询不适用,而且我们往往可以通过改写查询让MySQL高效地完成工作

4.2. UNION的限制

4.2.1. MySQL无法将限制条件从UNION的外层“下推”到内层,这使得原本能够限制部分返回结果的条件无法应用到内层查询的优化上

4.2.2. 从临时表中取出数据的顺序并不是一定的,所以如果想获得正确的顺序,还需要在最后的LIMIT操作前加上一个全局的ORDER BY操作

4.3. 等值传递

4.3.1. 优化器通过将列表复制到所有相关表中的相应列来“共享”列表

4.4. 并行执行

4.4.1. MySQL无法利用多核特性来并行执行查询

5. 优化特定类型的查询

5.1. 多数优化技巧都和特定的版本有关,所以对于未来MySQL的版本未必适用

5.2. 优化COUNT()查询

5.2.1. COUNT()是一个特殊的函数

5.2.1.1. 可以统计某列的值的数量

5.2.1.2. 可以统计行数

5.2.2. 用COUNT()的时候,这种情况下通配符并不会像我们猜想的那样扩展成所有的列,实际上,它会忽略所有的列而直接统计所有的行数

5.2.2.1. 如果想要知道结果中的行数,应该始终使用COUNT(*),这样可以更清晰地传达意图,避免糟糕的性能表现

5.2.3. 常见的错误之一是当需要统计行数时,在COUNT()函数的括号内指定了列名

5.2.4. 计算精确值非常复杂,而计算近似值则非常简单

5.2.4.1. 可以增加类似Memcached这样的外部缓存系统

5.3. 优化联接查询

5.3.1. 确保ON或者USING子句中的列上有索引

5.3.1.1. 没有用到的索引只会带来额外的负担

5.3.2. 确保任何GROUP BY和ORDER BY中的表达式只涉及一个表中的列,这样MySQL才有可能使用索引来优化这个过程

5.3.3. 当升级MySQL的时候需要注意:联接语法、运算符优先级等其他可能会发生变化的地方

5.3.4. 使用WITH ROLLUP优化GROUP BY

5.3.4.1. 分组查询的一个变种就是要求MySQL对返回的分组结果再做一次超级聚合

5.3.4.2. 在应用程序中做超级聚合是更好的,虽然这需要给客户端返回更多的结果

5.3.4.3. 最好的办法是尽可能地将WITH ROLLUP功能转移到应用程序中处理

5.4. 优化LIMIT和OFFSET子句

5.4.1. 在系统中需要进行分页操作的时候,我们通常会使用LIMIT加上偏移量的办法实现,同时加上合适的ORDER BY子句

5.4.2. 在页面中限制分页的数量

5.4.3. 优化大偏移量的性能

5.4.4. 尽可能地使用索引覆盖扫描,而不是查询所有的行

5.4.5. 将LIMIT查询转换为已知位置的查询,让MySQL通过范围扫描获得对应的结果

5.4.6. OFFSET的问题

5.4.6.1. 会导致MySQL扫描大量不需要的行然后再抛弃掉

5.4.6.2. 可以使用书签记录上次取数据的位置,那么下次就可以直接从该书签记录的位置开始扫描,这样就可以避免使用OFFSET

5.4.6.2.1. 无论翻页到多么靠后,其性能都会很好

5.4.6.3. 冗余表,冗余表只包含主键列和需要做排序的数据列

5.5. 更好的设计

5.5.1. 将具体的页数换成“下一页”按钮

5.5.1.1. 假设每页显示20条记录,那么我们每次查询时都是用LIMIT返回21条记录并只显示20条

5.5.1.2. 如果第21条存在,那么就显示“下一页”按钮,否则就说明没有更多的数据,也就无须显示“下一页”按钮了

5.5.2. 先获取并缓存较多的数据

5.5.2.1. 缓存1000条——然后每次分页都从这个缓存中获取

5.5.2.2. 如果结果集小于1000,就可以在页面上显示所有的分页链接,因为数据都在缓存中,所以这样做不会对性能造成影响

5.5.2.3. 如果结果集大于1000,则可以在页面上设计一个额外的“找到的结果多于1000条”之类的按钮

5.5.3. 比每次生成全部结果集再抛弃不需要的数据的效率高很多

5.6. 优化SQL CALC FOUND ROWS

5.6.1. 在LIMIT语句中加上SQL_CALC_FOUND_ROWS提示(hint),这样就可以获得去掉LIMIT以后满足条件的行数,因此可以作为分页的总数

5.6.2. 加上这个提示以后,不管是否需要,MySQL都会扫描所有满足条件的行,然后再抛弃掉不需要的行,而不是在满足LIMIT的行数后就终止扫描

5.6.3. 该提示的代价可能非常高

5.6.4. 当需要精确结果的时候,再单独使用COUNT(*)来满足需求,这时如果能够使用索引覆盖扫描则通常也会比SQL_CALC_FOUND_ROWS快得多

5.7. 优化UNION查询

5.7.1. 经常需要手工地将WHERE、LIMIT、ORDER BY等子句“下推”到UNION的各个子查询中,以便优化器可以充分利用这些条件进行优化

5.7.2. 除非你确实需要服务器消除重复的行,否则一定要使用UNION ALL

到了这里,关于读高性能MySQL(第4版)笔记12_查询性能优化(下)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 读高性能MySQL(第4版)笔记06_优化数据类型(上)

    3.2.2.1. 字符集和排序规则(collation)使字符型数据的比较更复杂 3.2.2.2. 应该将日期和时间存储为MySQL的内置类型而不是字符串类型 3.2.2.3. 应该用整型数据存储IP地址 4.1.1.1. 使用8、16、24、32和64位存储空间 5.2.4.1. VARCHAR(1000)的列则需要1002个字节,因为需要2字节存储长度

    2024年02月09日
    浏览(44)
  • 读高性能MySQL(第4版)笔记07_优化数据类型(下)

    2.3.1.1. 与UNIX时间戳相同 2.3.2.1. 会遇到2038年的问题 2.3.2.1.1. 使用带符号的32位INT,可以表达直到2038年的时间 2.3.2.1.2. 使用无符号的32位INT,可以表达直到2106年的时间 2.3.2.1.3. 使用64位,还可以超出这些范围 2.3.3.1. MySQL服务器、操作系统和客户端连接都有时区设置 2.3.3.2. 存

    2024年02月09日
    浏览(34)
  • 读高性能MySQL(第4版)笔记05_优化服务器设置

    2.1.3.1. MySQL只需要少量的内存就能保持一个连接(通常是一个相关的专用线程)打开 2.2.1.1. InnoDB缓冲池大小 2.2.1.2. 需要的内存比其他任何组件都多 2.2.1.3. 不仅缓存索引,还缓存行数据、自适应哈希索引、更改缓冲区、锁和其他内部结构等 2.2.1.4. InnoDB严重依赖缓冲池,应

    2024年02月09日
    浏览(45)
  • 读高性能MySQL(第4版)笔记04_操作系统和硬件优化

    4.9.2.1. 允许在内存中更改页面,而不用将更改刷新到磁盘,这通常涉及随机I/O,速度非常慢 4.9.2.2. 将更改的记录写入顺序日志文件,这样要快得多 4.9.2.3. 后台线程可以稍后将修改过的页面刷新到磁盘,这样做可以优化写操作的性能 5.11.2.1. 只有进行特殊的擦除操作之后,

    2024年02月09日
    浏览(34)
  • 高性能MySQL实战(三):性能优化

    大家好,我是 方圆 。这篇主要介绍对慢 SQL 优化的一些手段,而在讲解具体的优化措施之前,我想先对 EXPLAIN 进行介绍,它是我们在分析查询时必要的操作,理解了它输出结果的内容更有利于我们优化 SQL。为了方便大家的阅读,在下文中规定类似 key1 的表示二级索引,key_

    2024年02月11日
    浏览(50)
  • MySQL高性能优化规范建议

    数据库命令规范 数据库基本设计规范 1. 所有表必须使用 Innodb 存储引擎 2. 数据库和表的字符集统一使用 UTF8 3. 所有表和字段都需要添加注释 4. 尽量控制单表数据量的大小,建议控制在 500 万以内。 5. 谨慎使用 MySQL 分区表 6.尽量做到冷热数据分离,减小表的宽度 7. 禁止在表中建

    2024年02月12日
    浏览(43)
  • 《高性能MySQL》——创建高性能的索引(笔记)

    索引(在MySQL中也叫做“键(key)”) 是存储引擎用于快速找到记录的一种数据结构。 索引对于良好的性能非常关键。尤其是当表中的数据量越来越大时,索引对性能的影响愈发重要。 在数据量较小且负载较低时,不恰当的索引对性能的影响可能还不明显,但当数据量逐渐增大时

    2024年02月07日
    浏览(96)
  • 【QT性能优化】QT性能优化之QT6框架高性能模型视图代理框架千万级数据表分页查询优化

    QT性能优化之QT6框架高性能模型视图代理框架千万级数据表分页查询优化 简介 本文介绍了QT模型视图代理框架中的QT表格控件和QT数据库模块中的QT数据库查询模型结合使用的一个应用实践案例:QT高性能表格控件分页展示千万行数据。本文介绍了这个应用实践案例的运行效果

    2024年02月14日
    浏览(44)
  • 数据库——MySQL高性能优化规范

    所有数据库对象名称必须使用小写字母并用下划线分割 所有数据库对象名称禁止使用 MySQL 保留(如果表名中包含查询时,需要将其用单引号括起来) 数据库对象的命名要能做到见名识意,并且最后不要超过 32 个字符 临时库表必须以 tmp_为前缀并以日期为后缀,

    2024年02月11日
    浏览(95)
  • 读高性能MySQL(第4版)笔记08_创建高性能索引(上)

    2.4.2.1. 按照索引列中的数据大小顺序存储的 2.4.3.1. 键前缀查找只适用于根据最左前缀的查找 2.4.4.1. 在查询某些条件的数据时,存储引擎不再需要进行全表扫描 2.4.4.2. 通过比较节点页的值和要查找的值可以找到合适的指针进入下层子节点,这些指针实际上定义了子节点页中

    2024年02月08日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包