• MySQL如何避免全表扫描?


    MySQL如何避免全表扫描?

    这篇文章解释了何时以及为什么MySQL会执行全表扫描来解析查询,以及如何避免在大型表上进行不必要的全表扫描。

    何时会发生全表扫描

    MySQL使用全表扫描(在EXPLAIN输出中的type列显示为ALL)来解析查询的几种常见情况包括:

    • 表很小,进行表扫描比进行键查找更快。这通常出现在行数少于10行且行长度短的表上。
    • ONWHERE子句中没有可用的索引列的限制条件时。
    • 与常量值比较的索引列覆盖了表的太大部分,MySQL计算后认为表扫描会更快。
    • 使用低基数键(许多行匹配键值)通过另一列。在这种情况下,MySQL认为使用键可能需要许多键查找,而表扫描会更快。

    如何避免全表扫描

    对于小表,表扫描通常是适当的,对性能的影响可以忽略不计。对于大表,可以尝试以下技术来避免优化器错误地选择表扫描:

    • 使用ANALYZE TABLE tbl_name更新扫描表的键分布。

    • 对被扫描的表使用FORCE INDEX,以告诉MySQL与使用给定索引相比,表扫描的成本非常高:

      SELECT * FROM t1, t2 FORCE INDEX (index_for_column)
        WHERE t1.col_name=t2.col_name;
      
      • 1
      • 2
    • 启动mysqld时使用--max-seeks-for-key=1000选项,或使用SET max_seeks_for_key=1000,告诉优化器假设没有任何键扫描会导致超过1,000次键查找。这可以影响优化器的选择,使其倾向于使用索引而非执行表扫描。

    其他避免全面扫描的方式

    全表扫描通常在查询数据库时消耗大量资源,尤其是当表中的数据行数非常多时。避免全表扫描可以显著提高数据库查询的性能和效率。以下是一些有效的策略来避免全表扫描:

    使用索引

    • 创建合适的索引:这是避免全表扫描最有效的方法之一。通过对经常查询的列创建索引,MySQL可以直接定位到这些列的值,而不需要扫描整个表。
    • 多列索引:如果查询条件包含多个列,考虑创建组合索引。这样,MySQL可以利用索引来优化查询,尤其是在执行多列的比较和排序时。
    • 使用前缀索引:对于文本类较长的列,可以考虑使用前缀索引来减少索引大小和维护开销。

    优化查询语句

    • 精确的SELECT语句:尽量避免使用SELECT *,而是指定具体需要查询的字段。这不仅减少了数据传输的开销,也增加了利用索引的可能性。
    • 优化WHERE子句:确保WHERE子句中的条件能够利用索引。避免在索引列上使用函数或表达式,这可能导致索引失效。
    • 合理使用JOIN:在进行表连接时,确保连接的字段已经被索引。同时,尽量减少不必要的表连接操作。

    使用查询提示

    • FORCE INDEX:在某些情况下,MySQL可能不会选择最优的索引。你可以通过FORCE INDEX提示来强制MySQL使用特定的索引。
    • USE INDEX:与FORCE INDEX类似,但它的强制性较弱,仅建议MySQL使用指定的索引。

    其他策略

    • 分区表:对于极大的表,可以考虑使用分区技术。分区可以帮助缩小查询范围,从而减少扫描的数据量。
    • 定期维护索引:随着数据的增加和变化,索引可能会碎片化。定期对索引进行优化和重建,可以保持查询性能。
    • 使用缓存:对于频繁查询且不经常变更的数据,可以考虑使用查询缓存或者应用层缓存,减少对数据库的直接查询。

    参考链接

    在这里插入图片描述

  • 相关阅读:
    epoll使用实例
    windows“你尚未连接代理服务器可能有问题”解决方法
    serialVersionUID、transient关键字、Properties作为Map集合的使用、特有方法及和IO流结合的方法
    空域变换-直方图匹配(直方图规定化)
    二分法-数据类型定义导致的内存超限
    利用CloudCompare进行点云过滤去噪(统计滤波)
    git + docker + docker-compose + Jenkins+Linux 自动化构建、部署、测试过程
    STC89C51基础及项目第14天:循迹小车、跟随小车
    外包干了四年,人直接废了。。。
    品牌线上打假,应防微杜渐
  • 原文地址:https://blog.csdn.net/kaka_buka/article/details/138032769