MySQL旧版本ORDER BY 方法

MySQL 的order by 它涉及到三个参数:
A. sort_buffer_size 排序缓存。
B. read_rnd_buffer_size 第二次排序缓存。
C. max_length_for_sort_data 的最大排序约束。

我来简单说下MySQL的排序规则。
如果查询语句select * from tb1 where 1 order by  a ; 字段a没有建立索引。以上三个參数都足够大。

MySQL内部有两种排序规则:
第一种,是普通的排序。

这样的排序的特点是节省内存。可是终于会对磁盘有一次随机扫描。

大概主要步骤例如以下:
1. 因为没有WHERE条件,所以直接对磁盘进行全表扫描,把字段a以及每行的物理ID(如果为TID)拿出来。然后把全部拿到的记录全部放到sort_buffer_size中进行排序。
2. 依据排好序的TID。从磁盘随机扫描所须要的全部记录,排好序后再次把全部必须的记录放到read_rnd_buffer_size中。

另外一种,是冗余排序。

这样的排序的特点是不须要二次对磁盘进行随机扫描。可是缺点非常明显,太浪费内存空间。
跟第一种不同的是,在第一步里拿到的不不过字段a以及TID,而是把全部请求的记录全部拿到后,放到sort_buffer_size中进行排序。

这样能够直接从缓存中返回记录给client,不用再次从磁盘上获取一次。

从MySQL 5.7 后。对另外一种排序进行了打包压缩处理。避免太浪费内存。

比方对于varchar(255)来说,实际存储为varchar(3)。

那么相比之前的方式节约了好多内存。避免缓存区域不够时,建立磁盘暂时表。

下面为简单的演示
mysql> use t_girl;
Database changed

三个參数的详细值:

mysql> select truncate(@@sort_buffer_size/1024/1024,2)||‘MB‘ as ‘sort_buffer_size‘,truncate(@@read_rnd_buffer_size/1024/1024,2)||‘MB‘ as read_rnd_buffer_zie,@@max_length_for_sort_data as max_length_for_sort_data;
+------------------+---------------------+--------------------------+
| sort_buffer_size | read_rnd_buffer_zie | max_length_for_sort_data |
+------------------+---------------------+--------------------------+
| 2.00MB           | 2.00MB              |                     1024 |
+------------------+---------------------+--------------------------+
1 row in set (0.00 sec)

演示表的相关数据:

mysql> select table_name,table_rows,concat(truncate(data_length/1024/1024,2),‘MB‘) as ‘table_size‘ from information_schema.tables where table_name = ‘t1‘ and table_schema = ‘t_girl‘;
+------------+------------+------------+
| table_name | table_rows | table_size |
+------------+------------+------------+
| t1         |    2092640 | 74.60MB    |
+------------+------------+------------+
1 row in set (0.00 sec)

开启优化器跟踪:

mysql> SET OPTIMIZER_TRACE="enabled=on",END_MARKERS_IN_JSON=on;
Query OK, 0 rows affected (0.00 sec)

从数据字典里面拿到跟踪结果:

mysql> select * from information_schema.optimizer_trace\G
*************************** 1. row ***************************
                            QUERY: select * from t1 where id < 10 order by id
                            TRACE: {
  "steps": [
    {
      "join_preparation": {
        "select#": 1,
        "steps": [
          {
            "expanded_query": "/* select#1 */ select `t1`.`id` AS `id`,`t1`.`log_time` AS `log_time` from `t1` where (`t1`.`id` < 10) order by `t1`.`id`"
          }
        ] /* steps */
      } /* join_preparation */
    },
    {
      "join_optimization": {
        "select#": 1,
        "steps": [
          {
            "condition_processing": {
              "condition": "WHERE",
              "original_condition": "(`t1`.`id` < 10)",
              "steps": [
                {
                  "transformation": "equality_propagation",
                  "resulting_condition": "(`t1`.`id` < 10)"
                },
                {
                  "transformation": "constant_propagation",
                  "resulting_condition": "(`t1`.`id` < 10)"
                },
                {
                  "transformation": "trivial_condition_removal",
                  "resulting_condition": "(`t1`.`id` < 10)"
                }
              ] /* steps */
            } /* condition_processing */
          },
          {
            "table_dependencies": [
              {
                "table": "`t1`",
                "row_may_be_null": false,
                "map_bit": 0,
                "depends_on_map_bits": [
                ] /* depends_on_map_bits */
              }
            ] /* table_dependencies */
          },
          {
            "ref_optimizer_key_uses": [
            ] /* ref_optimizer_key_uses */
          },
          {
            "rows_estimation": [
              {
                "table": "`t1`",
                "table_scan": {
                  "rows": 2092640,
                  "cost": 4775
                } /* table_scan */
              }
            ] /* rows_estimation */
          },
          {
            "considered_execution_plans": [
              {
                "plan_prefix": [
                ] /* plan_prefix */,
                "table": "`t1`",
                "best_access_path": {
                  "considered_access_paths": [
                    {
                      "access_type": "scan",
                      "rows": 2.09e6,
                      "cost": 423303,
                      "chosen": true,
                      "use_tmp_table": true
                    }
                  ] /* considered_access_paths */
                } /* best_access_path */,
                "cost_for_plan": 423303,
                "rows_for_plan": 2.09e6,
                "sort_cost": 2.09e6,
                "new_cost_for_plan": 2.52e6,
                "chosen": true
              }
            ] /* considered_execution_plans */
          },
          {
            "attaching_conditions_to_tables": {
              "original_condition": "(`t1`.`id` < 10)",
              "attached_conditions_computation": [
              ] /* attached_conditions_computation */,
              "attached_conditions_summary": [
                {
                  "table": "`t1`",
                  "attached": "(`t1`.`id` < 10)"
                }
              ] /* attached_conditions_summary */
            } /* attaching_conditions_to_tables */
          },
          {
            "clause_processing": {
              "clause": "ORDER BY",
              "original_clause": "`t1`.`id`",
              "items": [
                {
                  "item": "`t1`.`id`"
                }
              ] /* items */,
              "resulting_clause_is_simple": true,
              "resulting_clause": "`t1`.`id`"
            } /* clause_processing */
          },
          {
            "refine_plan": [
              {
                "table": "`t1`",
                "access_type": "table_scan"
              }
            ] /* refine_plan */
          }
        ] /* steps */
      } /* join_optimization */
    },
    {
      "join_execution": {
        "select#": 1,
        "steps": [
          {
            "filesort_information": [
              {
                "direction": "asc",
                "table": "`t1`",
                "field": "id"
              }
            ] /* filesort_information */,
            "filesort_priority_queue_optimization": {
              "usable": false,
              "cause": "not applicable (no LIMIT)"
            } /* filesort_priority_queue_optimization */,
            "filesort_execution": [
            ] /* filesort_execution */,
            "filesort_summary": {
              "rows": 62390,
              "examined_rows": 2097152,
              "number_of_tmp_files": 0,
              "sort_buffer_size": 2097152,
              "sort_mode": "<sort_key, additional_fields>"
            } /* filesort_summary */
          }
        ] /* steps */
      } /* join_execution */
    }
  ] /* steps */
}
MISSING_BYTES_BEYOND_MAX_MEM_SIZE: 0
          INSUFFICIENT_PRIVILEGES: 0
1 row in set (0.00 sec)

mysql>

当中以上红色部分<sort_key, additional_fields> 表示用了另外一种排序规则。

其它的两种<sort_key, rowid> 以及<sort_key, packed_additional_fields>分别代表第一种和兴许版本号MySQL的提上涨。 走自己的经验。

版权声明:本文博主原创文章,博客,未经同意不得转载。

时间: 2024-10-20 01:50:37

MySQL旧版本ORDER BY 方法的相关文章

MySQL新旧版本ORDER BY 处理方法

MySQL 的order by 涉及到三个参数:A. sort_buffer_size 排序缓存.B. read_rnd_buffer_size 第二次排序缓存.C. max_length_for_sort_data 带普通列的最大排序约束. 我来简单说下MySQL的排序规则.假设查询语句select * from tb1 where 1 order by  a ; 字段a没有建立索引:以上三个参数都足够大.MySQL内部有两种排序规则:第一种,是普通的排序.这种排序的特点是节省内存,但是最终会

查看mysql数据库版本方法总结

当你接手某个mysql数据库管理时,首先你需要查看维护的mysql数据库版本:当开发人员问你mysql数据库版本时,而恰好你又遗忘了,那么此时也需要去查看mysql数据库的版本...............下文总结一下Linux平台下查看mysql数据库的方法.个人觉得总结的比较全面了. 方法1:登录数据库时,你可以看到对应mysql数据库的版本信息,如下所示: [[email protected] ~]# mysql -u root -p Enter password: Welcome to

如何下载旧版本的MySQL

可能存在这样的场景,比如一些老系统需要使用MySQL 5.5版本才能运行,其余的不行. 1.登录下载站点 https://dev.mysql.com/downloads/mysql/ 此时的最新版本为5.7.18. 2.旧版本下载入口 Looking for previous GA versions? 3.下载对应版本: 可以看出下载列表上已经包含了以往版本,对应下载即可. 4.DEB Bundle与DEB Package的区别 DEB Bundle是将deb文件全部打包成一个压缩包,解压出来全

linux,apache,php,mysql常用的查看版本信息的方法

1. 查看linux的内核版本,系统信息,常用的有三种办法: uname -a:   more /etc/issue;    cat /proc/version; 2. 查看apache的版本信息,如果是通过yum,或者是rpm安装的,可以使用rpm -qa |gerp httpd 来查看: 还可以通过httpd -v来查询: 当然,安装好apache后,可以直接elink回环查看apache的信息. 3.查看php的版本信息,如果是通过yum,或者是rpm包安装的,可以使用rpm -qa |g

MySQL表类型和存储引擎版本不一致解决方法

使用的是老版本的mysql客户端Navicate 8 ,mysql 服务端用的是mysql5.6的版本,在修改版本引擎的时候出现版本不对; mysql error ‘TYPE=MyISAM’ 解决办法: Replace TYPE=MyISAM with ENGINE=MyISAM The problem was “TYPE=MyISAM” which should be “ENGINE=MyISAM” as per MySQL version updates – a simple search

查看MySQL数据库版本方法总结!

前言: 当你接手某个mysql数据库管理时,首先你需要查看维护的mysql数据库版本,或者当开发人员问你mysql数据库版本时,而恰好你又遗忘了,那么此时也需要去查看mysql数据库的版本.这些是我自己搜集的,分享给大家! 1.如果你是yum安装 rpm -qa|grep mysql或者rpm -qa|grep -i mysql mysql-server-5.1.73-3.el6_5.x86_64 如果你能登陆数据库 2.登陆时查看  mysql -u root -p 3.mysql> sele

mysql防止重复插入记录方法总结

防止mysql重复插入记录的方法有很多种,常用的是ignore,Replace,ON DUPLICATE KEY UPDATE,当然我们也可以在php中加以判断了. 方案一:使用ignore关键字 如果是用主键primary或者唯一索引unique区分了记录的唯一性,避免重复插入记录可以使用: 代码如下:  代码如下 复制代码  INSERT IGNORE INTO `table_name` (`email`, `phone`, `user_id`) VALUES ('[email protec

MySQL性能调优的方法

第一种方法 1.选取最适用的字段属性 MySQL可以很好的支持大数据量的存取,但是一般说来,数据库中的表越小,在它上面执行的查询也就会越快.因此,在创建表的时候,为了获得更好的 性能,我们可以将表中字段的宽度设得尽可能小.例如,在定义邮政编码这个字段时,如果将其设置为CHAR(255),显然给数据库增加了不必要的空间,甚 至使用VARCHAR这种类型也是多余的,因为CHAR(6)就可以很好的完成任务了.同样的,如果可以的话,我们应该使用MEDIUMINT而不是 BIGIN来定义整型字段. 另外一

优化MySQL数据库性能的八大方法

本文探讨了提高MySQL 数据库性能的思路,并从8个方面给出了具体的解决方法. 1.选取最适用的字段属性 MySQL可以很好的支持大数据量的存取,但是一般说来,数据库中的表越小,在它上面执行的查询也就会越快.因此,在创建表的时候,为了获得更好的性能,我们可以将表中字段的宽度设得尽可能小.例如,在定义邮政编码这个字段时,如果将其设置为CHAR(255),显然给数据库增加了不必要的空间,甚至使用VARCHAR这种类型也是多余的,因为CHAR(6)就可以很好的完成任务了.同样的,如果可以的话,我们应该