二、MYSQL相关参数 sort_buffer_size: 当然也就是每次排序的buffer,用作内部快速排序用,如果buffer越大当然产生的物理文件也就越少,但是这个参数是会话级别的,过分加大会造成内存不足,默认256K。注意: On Linux, there are thresholds of 256KB and 2MB where larger values may significantly slow down memory allocation, so you should consider staying below one of those values
3、5.7.3后一次访问排序算法的优化 使用一个叫做pack优化的方法,目的在于压缩NULL减少一次访问排序算法对sort buffer和tempfile的过多使用 原文: without packing, a VARCHAR(255) column value containing only 3 characters takes 255 characters in the sort buffer. With packing, the value requires only 3 characters plus a two-byte length indicator. NULL values require only a bitmask. 但是我在做MYSQL TRACE的时候发现这还有一个unpack的过程,并且每一行每一个字段都需要pack unpack 随后证明
分别在max_length_for_sort_data为1024和max_length_for_sort_data为4对 select * from testmer order by id1; 生成trace文件 意义也就是使用一次访问排序和二次访问排序,因为数据量少也就在sort_buffer 排序就好了。
mysql> select count(*) from testshared3; +----------+ | count(*) | +----------+ | 1048576 | +----------+ 1 row in set (28.31 sec)
mysql> set sort_buffer_size=50000; Query OK, 0 rows affected (0.00 sec)
mysql> show variables like "%sort_buffer_size%"; +-------------------------+---------+ | Variable_name | Value | +-------------------------+---------+ | sort_buffer_size | 50000 | +-------------------------+---------+
mysql> show status like "%Sort_merge%"; +-------------------+-------+ | Variable_name | Value | +-------------------+-------+ | Sort_merge_passes | 0 | +-------------------+-------+ 1 row in set (0.00 sec)
mysql> explain select * from testshared3 order by id limit 1048570,1; +----+-------------+-------------+------------+------+---------------+------+---------+------+---------+----------+----------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------------+------------+------+---------------+------+---------+------+---------+----------+----------------+ | 1 | SIMPLE | testshared3 | NULL | ALL | NULL | NULL | NULL | NULL | 1023820 | 100.00 | Using filesort | +----+-------------+-------------+------------+------+---------------+------+---------+------+---------+----------+----------------+ mysql> select * from testshared3 order by id limit 1048570,1; +------+ | id | +------+ | 1 | +------+ 1 row in set (5 min 4.76 sec) 完成后 mysql> show status like "%Sort_merge%"; +-------------------+-------+ | Variable_name | Value | +-------------------+-------+ | Sort_merge_passes | 63 | +-------------------+-------+ 1 row in set (0.21 sec)
opt: number_of_tmp_files: 378 临时文件数量378
然后加大sort_buffer_size
mysql> show variables like "%sort_buffer_size%"; +-------------------------+---------+ | Variable_name | Value | +-------------------------+---------+ | sort_buffer_size | 262144 | +-------------------------+---------+
mysql> show status like "%Sort_merge%"; +-------------------+-------+ | Variable_name | Value | +-------------------+-------+ | Sort_merge_passes | 0 | +-------------------+-------+ 1 row in set (0.04 sec)
还是同样的语句
mysql> select * from testshared3 order by id limit 1048570,1; +------+ | id | +------+ | 1 | +------+ 1 row in set (5 min 4.76 sec) mysql> show status like "%Sort_merge%"; +-------------------+-------+ | Variable_name | Value | +-------------------+-------+ | Sort_merge_passes | 11 | +-------------------+-------+ opt: number_of_tmp_files: 73 临时文件数量73
(gdb) n 250 if (param->sort_length < 10) (gdb) list 245 than quicksort seems to be somewhere around 10 to 40 records. 246 So we"re a bit conservative, and stay with quicksort up to 100 records. 247 */ 248 if (count <= 100) 249 { 250 if (param->sort_length < 10) 251 { 252 std::sort(m_sort_keys, m_sort_keys + count, 253 Mem_compare(param->sort_length)); 254 return;
这部分mysql上的源码/* std::stable_sort has some extra overhead in allocating the temp buffer, which takes some time. The cutover point where it starts to get faster than quicksort seems to be somewhere around 10 to 40 records. So we"re a bit conservative, and stay with quicksort up to 100 records. */ if (count <= 100) { if (param->sort_length < 10) { std::sort(m_sort_keys, m_sort_keys + count, Mem_compare(param->sort_length)); return; } std::sort(m_sort_keys, m_sort_keys + count, Mem_compare_longkey(param->sort_length)); return; } // Heuristics here: avoid function overhead call for short keys. if (param->sort_length < 10) { std::stable_sort(m_sort_keys, m_sort_keys + count, Mem_compare(param->sort_length)); return; } std::stable_sort(m_sort_keys, m_sort_keys + count, Mem_compare_longkey(param->sort_length));最后附上快速排序的代码 带排序数据是13,3,2,9,34,5,102,90,20,2 排序完成后如下: gaopeng@bogon:~/datas$ ./a.out sort result:2 2 3 5 9 13 20 34 90 102/************************************************************************* > File Name: qsort.c > Author: gaopeng QQ:22389860 > Mail: gaopp_200217@163.com > Created Time: Fri 06 Jan 2017 03:04:08 AM CST ************************************************************************/ #include<stdio.h> #include<stdlib.h> int partition(int *k,int low,int high) { int point; point = k[low]; //基准点,采用数组的第一个值,这里实际可以优化 while(low<high) //等待low=high一趟交换完成 { while(low<high && k[high] >=point) //过滤掉尾部大于基准点的值,不需要交换 { high--; } k[low] = k[high]; //基准点多次交换为无谓交换直接赋值即可 while(low<high && k[low] <=point) //过滤掉头部小于基准点的值,不需要交换 { low++; } k[high] = k[low]; //基准点多次交换为无谓交换直接赋值即可 } k[low] = point; return low; }int q_sort(int *k,int low,int high) { int point; if(low<high) { point = partition(k,low,high); q_sort(k,low,point-1); //实现递归前半部分 q_sort(k,point+1,high); //实现递归后半部分 } return 0; }int main() { int i,a[10]={13,3,2,9,34,5,102,90,20,2}; //测试数据 q_sort(a,0,9); //数组下标0 9 printf("sort result:"); for(i=0;i<10;i++) { printf("%d ",a[i]); } printf("
"); }本文永久更新链接地址