【GreatSQL优化器-03】查询开销估算

GreatSQL vs MySQL性能测试来了,速围观~ 无论ibp(innodb_buffer_pool_size)是否充足,MySQL的性能都远不如GreatSQL。MySQL的性能平均约为GreatSQL的70%(最高84.5%,最低61.7%)。在ibp充分的情况下,随着并发数的增加,MySQL并没有表现出该有的性能提升,反倒掉头向下,可见还是不够稳定。在ibp不够的情况下,GreatSQL开启thread pool性能有所提升;当ibp充足的情况下,区别就不大了。MySQL vs GreatSQL性能数据对比各数据库版本分别为。 阅读详情

【GreatSQL优化器-03】查询开销估算

一、cost和read_time介绍

GreatSQL的优化器在创建执行计划的时候是根据每张表的行数和数据分布以及读数据硬盘消耗等信息来判断先查询哪张表后查询哪张表,要不要使用索引,这些表资源信息就被称为cost,俗称为"开销"。在这之前已经执行了update_ref_and_keys(参考【GreatSQL优化器-02】)和extract_const_tables(参考【GreatSQL优化器-01】),拿到了const tables信息和表的keyuse_array索引信息,这里就开始计算单张表扫描的开销,做一个初步的估计,用来给后面的choose_table_order()搜索最佳表顺序提供原始数据信息。

优化器通过estimate_rowcount函数初步计算单表开销,这个函数最后会计算出3个重要的数据。

名称说明计算公式
found_records表的总行数tab->table()->file->stats.records
read_time读取所有数据需要的开销io_cost + cpu_cost + import_cost
worst_seeks扫描全表需要的最差开销find_worst_seeks(tab->table(), tab->found_records, tab->read_time)根据上面2项计算得出

下面用一个简单的例子来说明这三个数字怎么查看:

greatsql> CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 INT,date1 DATETIME);
greatsql> INSERT INTO t1 VALUES (1,10,'2021-03-25 16:44:00.123456'),(2,1,'2022-03-26 16:44:00.123456'),(3,4,'2023-03-27 16:44:00.123456'),(5,5,'2024-03-25 16:44:00.123456');
greatsql> CREATE TABLE t2 (cc1 INT PRIMARY KEY, cc2 INT);
greatsql> INSERT INTO t2 VALUES (1,3),(2,1),(3,2),(4,3),(5,15);
greatsql> CREATE INDEX idx1 ON t1(c2);
greatsql> CREATE INDEX idx2 ON t1(c2,date1);
greatsql> CREATE INDEX idx2_1 ON t2(cc2);
greatsql> SET optimizer_trace = 'enabled=ON' ;

greatsql> SELECT * FROM t2,t1,(select 10) t3 where t1.c1=t2.cc2;
+-----+------+----+------+---------------------+----+
| cc1 | cc2  | c1 | c2   | date1               | 10 |
+-----+------+----+------+---------------------+----+
|   3 |    2 |  2 |    1 | 2022-03-26 16:44:00 | 10 |
|   1 |    3 |  3 |    4 | 2023-03-27 16:44:00 | 10 |
|   4 |    3 |  3 |    4 | 2023-03-27 16:44:00 | 10 |
|   2 |    1 |  1 |   10 | 2021-03-25 16:44:00 | 10 |
+-----+------+----+------+---------------------+----+
> SELECT * FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE;
          {
            "rows_estimation": [
              {
                "table": "`t2`",  -- 按照上面查询顺序t2放第一个
                "table_scan": {
                  "rows": 5, 因为t2非const表,因此这里显示的是所有行
                  "cost": 0.25, 这个是t2查询5条的开销,
                  "worst_seeks": 2 这里是另外加上去的,为了查看方便
                }
              },
              {
                "table": "`t1`", 按照上面查询顺序t1放第二个
                "table_scan": {
                  "rows": 4, 因为t1非const表,因此这里显示的是所有行
                  "cost": 0.25,
                  "worst_seeks": 2 这里是另外加上去的,为了查看方便
                }
              },
              {
                "table": " `t3`", 按照上面查询顺序t3放第三个
                "rows": 1,
                "cost": 1, ※这里有疑问,实际的read_time=worst_seeks=0.25,但是代码用了固定值1
                "worst_seeks": 0.25 这里是另外加上去的,为了查看方便
                "table_type": "system", 因为t3是const表,因此这里显示的system
                "empty": false
              }
            ]
          },

附表:代价系数

代价系数值说明
ROW_EVALUATE_COST0.1扫描一行需要的开销
KEY_COMPARE_COST0.05比较row id需要的开销
MEMORY_TEMPTABLE_CREATE_COST1.0创建临时表的开销,等于读10行
MEMORY_TEMPTABLE_ROW_COST0.1读或写一行到临时表
DISK_TEMPTABLE_CREATE_COST20.0创建MyISAM表的开销
DISK_TEMPTABLE_ROW_COST0.5按顺序生成 MyISAM 行的开销
MEMORY_BLOCK_READ_COST0.25读一个block从一个memory buffer pool
IO_BLOCK_READ_COST1.0从磁盘读取block
二、estimate_rowcount代码执行过程

实际代码执行过程如下,其中test_quick_select()函数在下面第三节介绍:

bool JOIN::make_join_plan() {
  if (estimate_rowcount()) return true;
}

bool JOIN::estimate_rowcount() {
        // 遍历每张表,计算每张表的上面3个值
        for (JOIN_TAB *tab = join_tab; tab < tab_end; tab++) {
            // 计算下面几个值
        tab->set_records(tab->found_records = tab->table()->file->stats.records);
        const Cost_estimate table_scan_time = tab->table()->file->table_scan_cost();
        tab->read_time = table_scan_time.total_cost();
        tab->worst_seeks =
            find_worst_seeks(tab->table(), tab->found_records, tab->read_time);
                // 这个函数是副功能,用于发现可能用于 GROUP BY 或 DISTINCT 查询的索引或可能用于 SKIP SCAN 的索引。
                // 主要给skip_scan_keys和const_keys添加可以用的索引
                add_loose_index_scan_and_skip_scan_keys(this, tab);
                // 如果上面计算得到的read_time<= 2.0那就不做快速查询test_quick_select()直接返回了,但是如果大于的话就要找是否有索引用快速查询来估算开销了。
                get_quick_record_count();
        }
}

上面涉及的参数值见下表。

细项说明计算公式
table_scan_cost()引擎层读表的开销((stats.data_file_length) / IO_SIZE + 2) * table->cost_model()->page_read_cost(1.0)
find_worst_seeks()全表扫描所需的最多开销worst_seeks = min(table->file->worst_seek_times(tab->found_records / 10), tab->read_time * 3); min_worst_seek = table->file->worst_seek_times(2.0); 结果为:std::max(worst_seeks, min_worst_seek);
三、计算单表cost举例说明
例子1:SELECT * FROM t1 join t2 ON t1.c1=t2.cc1 and t2.cc1=t1.c1 or t1.c1=5;
          {
            "rows_estimation": [
              {
                "table": "`t1`",
                "range_analysis": {
                  "table_scan": {
                    "rows": 4,
                    "cost": 3.5 这里算出来的开销大于2了,因此要走test_quick_select()估算
                  },
                  "potential_range_indexes": [ 这里开始循环t1的所有索引,找出条件涉及的索引
                    {
                      "index": "PRIMARY", 条件涉及到了t1.c1,因此这里PRIMARY索引被使用
                      "usable": true,
                      "key_parts": [
                        "c1"
                      ]
                    },
                    {
                      "index": "idx1", 条件不涉及idx1,因此这里idx1索引不被使用
                      "usable": false,
                      "cause": "not_applicable"
                    },
                    {
                      "index": "idx2", 条件不涉及idx2,因此这里idx2索引不被使用
                      "usable": false,
                      "cause": "not_applicable"
                    }
                  ],
                  "best_covering_index_scan": { 通过find_shortest_key()找到的最短的索引,指覆盖所有需要的数据的联合索引table->covering_keys
                    "index": "idx2", 这个值为table->covering_keys,联合索引包含了主键信息
                    "cost": 1.40548, 开销小于上面的最早算出来的3.5,因此被选择。这里io_cost=1.00548,cpu_cost=4行*0.1(读每行开销)
                    "chosen": true
                  },
                  "setup_range_conditions": [ 没有找到mm tree
                  ],
                  "group_index_range": { 不是GROUP语句
                    "chosen": false,
                    "cause": "not_single_table"
                  },
                  "skip_scan_range": { 没有配置skip_scan,不需要skip_scan
                    "chosen": false,
                    "cause": "not_single_table"
                  }
                }
              },
              {
                "table": "`t2`",
                "table_scan": {
                  "rows": 5,
                  "cost": 1 表t2算出来的开销小于2,因此不继续用快速查询计算了。
                }
              }
            ]
          },
-- t1选择索引 idx2,因为cost更小
-- t2的选择结果需要结合后面的choose_table_order()看,下一期再讲
greatsql> EXPLAIN SELECT * FROM t1 join t2 ON t1.c1=t2.cc1 and t2.cc1=t1.c1 or t1.c1=5;
+----+-------------+-------+------------+-------+---------------+--------+---------+------+------+----------+---------------------------------------------------------+
| id | select_type | table | partitions | type  | possible_keys | key    | key_len | ref  | rows | filtered | Extra                                                   |
+----+-------------+-------+------------+-------+---------------+--------+---------+------+------+----------+---------------------------------------------------------+
|  1 | SIMPLE      | t1    | NULL       | index | PRIMARY       | idx2   | 11      | NULL |    4 |   100.00 | Using index                                             |                               这里选择了idx2索引扫描,跟上面算出来的结论一致
|  1 | SIMPLE      | t2    | NULL       | index | PRIMARY       | idx2_1 | 5       | NULL |    5 |   100.00 | Using where; Using index; Using join buffer (hash join) |
+----+-------------+-------+------------+-------+---------------+--------+---------+------+------+----------+---------------------------------------------------------+

看另一个例子:

例子2:SELECT * FROM t1 join t2 ON t1.c1=t2.cc1 and t1.c1<5;
          {
            "rows_estimation": [
              {
                "table": "`t1`",
                "range_analysis": {
                  "table_scan": {
                    "rows": 4,
                    "cost": 3.5 这里算出来的开销大于2了,因此要走test_quick_select()估算
                  },
                  "potential_range_indexes": [
                    {
                      "index": "PRIMARY", 条件涉及到了t1.c1,因此这里PRIMARY索引被使用
                      "usable": true,
                      "key_parts": [
                        "c1"
                      ]
                    },
                    {
                      "index": "idx1", 条件不涉及idx1,因此这里idx1索引不被使用
                      "usable": false,
                      "cause": "not_applicable"
                    },
                    {
                      "index": "idx2", 条件不涉及idx2,因此这里idx2索引不被使用
                      "usable": false,
                      "cause": "not_applicable"
                    }
                  ],
                  "best_covering_index_scan": { 找到联合索引,包含了主键信息
                    "index": "idx2",
                    "cost": 1.40548,
                    "chosen": true
                  },
                  "setup_range_conditions": [
                  ],
                  "group_index_range": { 不是GROUP语句
                    "chosen": false,
                    "cause": "not_single_table"
                  },
                  "skip_scan_range": { 没有配置skip_scan,不需要skip_scan
                    "chosen": false,
                    "cause": "not_single_table"
                  },
                  "analyzing_range_alternatives": {
                    "range_scan_alternatives": [
                      {
                        "index": "PRIMARY", 根据get_best_group_min_max算出来的mm tree找到的最佳索引
                        "ranges": [
                          "c1 < 5"
                        ],
                        "index_dives_for_eq_ranges": true,
                        "rowid_ordered": true,
                        "using_mrr": false,
                        "index_only": false,
                        "in_memory": 0,
                        "rows": 3, 范围扫描c1 < 5找到的符合的条数3条
                        "cost": 1.31293, 比上面算出来的cost低,因此被选择
                        "chosen": true
                      }
                    ],
                    "analyzing_roworder_intersect": {
                      "usable": false,
                      "cause": "too_few_roworder_scans" 因为tree->n_ror_scans < 2,所以没有被选择
                    }
                  },
                  "chosen_range_access_summary": { 总结上面所有计算的结果得出结论
                    "range_access_plan": {
                      "type": "range_scan", 结论是走索引范围扫描
                      "index": "PRIMARY",
                      "rows": 3,
                      "ranges": [
                        "c1 < 5"
                      ]
                    },
                    "rows_for_plan": 3, 找到3条数据
                    "cost_for_plan": 1.31293,
                    "chosen": true
                  }
                }
              },
              {
                "table": "`t2`",
                "range_analysis": {
                  "table_scan": {
                    "rows": 5,
                    "cost": 3.6 这里算出来的开销大于2了,因此要走test_quick_select()估算
                  },
                  "potential_range_indexes": [
                    {
                      "index": "PRIMARY", 涉及到主键列,因此用到了
                      "usable": true,
                      "key_parts": [
                        "cc1"
                      ]
                    },
                    {
                      "index": "idx2_1", 没有涉及cc2,因此没有用到
                      "usable": false,
                      "cause": "not_applicable"
                    }
                  ],
                  "best_covering_index_scan": { 找到的非唯一索引,开销比上面的小,被选择
                    "index": "idx2_1",
                    "cost": 1.50439,
                    "chosen": true
                  },
                  "setup_range_conditions": [
                  ],
                  "group_index_range": {
                    "chosen": false,
                    "cause": "not_single_table"
                  },
                  "skip_scan_range": {
                    "chosen": false,
                    "cause": "not_single_table"
                  },
                  "analyzing_range_alternatives": {
                    "range_scan_alternatives": [
                      {
                        "index": "PRIMARY",
                        "ranges": [
                          "cc1 < 5"
                        ],
                        "index_dives_for_eq_ranges": true,
                        "rowid_ordered": true,
                        "using_mrr": false,
                        "index_only": false,
                        "in_memory": 0,
                        "rows": 4, 根据cc1 < 5条件找到4条数据记录
                        "cost": 1.4133, 开销更小,被选择
                        "chosen": true
                      }
                    ],
                    "analyzing_roworder_intersect": {
                      "usable": false,
                      "cause": "too_few_roworder_scans"
                    }
                  },
                  "chosen_range_access_summary": { 总结上面所有计算的结果得出结论
                    "range_access_plan": {
                      "type": "range_scan",  结论是走索引范围扫描
                      "index": "PRIMARY",
                      "rows": 4,
                      "ranges": [
                        "cc1 < 5"
                      ]
                    },
                    "rows_for_plan": 4, 找到4条记录
                    "cost_for_plan": 1.4133,
                    "chosen": true
                  }
                }
              }
            ]
          },

-- 结论:t1表用了范围扫描,跟上面结论一致
-- t2的选择结果需要结合后面的best_access_path()看,下一期再讲
greatsql> EXPLAIN SELECT * FROM t1 join t2 ON t1.c1=t2.cc1 and t1.c1<5;
+----+-------------+-------+------------+--------+---------------+---------+---------+-----------+------+----------+-------------+
| id | select_type | table | partitions | type   | possible_keys | key     | key_len | ref       | rows | filtered | Extra       |
+----+-------------+-------+------------+--------+---------------+---------+---------+-----------+------+----------+-------------+
|  1 | SIMPLE      | t1    | NULL       | range  | PRIMARY       | PRIMARY | 4       | NULL      |    3 |   100.00 | Using where |                                    
|  1 | SIMPLE      | t2    | NULL       | eq_ref | PRIMARY       | PRIMARY | 4       | db1.t1.c1 |    1 |   100.00 | NULL        |
+----+-------------+-------+------------+--------+---------------+---------+---------+-----------+------+----------+-------------+
四、总结

从上面优化器最早的步骤我们认识了优化器的cost和计算方式,知道了如何初步估算单表的扫描cost并且按照最小cost选择最佳索引,这些单表估算出来的cost会在后面greedy_search(贪婪搜索)的时候用来做为计算依据,然后按照每张表的扫描开销对表进行排序,算出哪张表先扫描哪张表后扫描,最后得出最佳执行计划。

需要注意的是,上面的初步估算cost<=2的时候是不会进行后续快速扫描计算的,因此如果实际运用中想查看表的正确cost的话,需要根据当时表的实际数据量来做执行计划计算,而不是在空表或者数据量很小时候先做一次执行计划,然后用这个结果得出结论。

Enjoy GreatSQL :)

关于 GreatSQL

GreatSQL是适用于金融级应用的国内自主开源数据库,具备高性能、高可靠、高易用性、高安全等多个核心特性,可以作为MySQL或Percona Server的可选替换,用于线上生产环境,且完全免费并兼容MySQL或Percona Server。

相关链接: GreatSQL社区 Gitee GitHub Bilibili

GreatSQL社区:

image

社区有奖建议反馈: https://greatsql.cn/thread-54-1-1.html

社区博客有奖征稿详情: https://greatsql.cn/thread-100-1-1.html

(对文章有疑问或者有独到见解都可以去社区官网提出或分享哦~)

技术交流群:

微信&QQ群:

QQ群:533341697

微信群:添加GreatSQL社区助手(微信号:wanlidbc )好友,待社区助手拉您进群。

虚拟机器人平台CoppeliaSim(Vrep)的逆运动学教学 相信看这篇博客的人都知道CoppeliaSim是做什么的,因此这里不多赘述。CoppeliaSim从最早的Vrep到现在已经更新了N个版本,从过去Vrep3.x开始使用的我这里小小地吐槽一下这个软件。CoppeliaSim每一个版本都有更新,问题是这些更新有时候不能向前兼容,而且时不时更新地让人不知所措(对于有紧急任务的时候真的很火大啊)。 以本文所展示地逆运动学来说,CoppeliaSim在4.0.0之后又大变,推翻了过往所有的拖动模块链接之类的构建方式,转而采用直接通过代码来实现逆运动学。 简单版逆运动 阅读详情

相关推荐

07. 基础实战篇 - STP的基本配置

STP(生成数协议)是一个用于在局域网中消除环路的协议,他的标准是IEEE802.1d。STP通过强制使部分冗余链路处于阻塞状态,其它链路处于转发状态,将环形网络结构修剪成无环路的树形网络结构。可实现消除环路,当处于转发状态的链路不可用时,STP重新配置网络,并激活合适的备用链路状态,恢复网络连通性。

weixin_39868387的博客 7225

MySQL开发技巧 - 分页和索引

当一个表中有很多符合查询条件的数据的时候,我们往往不需要把他们全部一次性取出来,那样对查询效率或者服务器性能来说都会是一个极大的挑战:例如最简单的商城,假设商城中有一万个数据,但我们在前端可能只会每次看到一页10个左右的数据,当我们浏览完这十个商品后,点击下一页浏览其他的商品,这样的分页浏览,对实际存储商品数据的MySQL数据库来说,实际上就是使用了MySQL的分页查询功能。那么我们该怎么实现分页查询呢?索引是一张特殊的表,该表保存了主键与索引字段,并指向实体表的记录。先假设有一张表student。

2201_75609739的博客 2116

Buck电路中自举电容串联小电阻的作用

在Buck电路中,自举电容(Cboot)驱动高边MOSFET时,因寄生电感和电容会形成LC谐振回路,导致SW节点高频振铃,引发EMI问题。串联小电阻(Rboot)可引入阻尼效应,抑制振铃、改善波形和EMI性能,但会略微增加开关损耗。设计时建议预留可调电阻位(2Ω~20Ω),根据实测结果平衡效率与系统稳定性,提升电源可靠性。这一措施是优化开关电源EMC的常见实践。

硬核科技 626

GreatSQL体系架构的了解

通过学习《图文结合带你搞懂GreatSQL体系架构》,能对GreatSQL的基本底层原理有所了解。一张经典的体系架构图,图1_GreatSQL5.7 版本体系架构图由此可以发现,GreatSQL5.7由以下几部分组成,连接池组件系统管理和控制工具SQL接口组件查询解析器查询优化器缓存组件可插拔存储引擎系统和日志文件GreatSQL数据库区别于其他数据库的一个特点就是其可插拔的表存储引擎,特别需要注...

bisal的专栏 409

从SGX到TDX:英特尔机密计算的技术演进与选型指南

本文深入解析了英特尔两代机密计算技术SGX与TDX的核心差异与选型策略。SGX提供应用级飞地隔离,安全等级高但开发复杂;TDX提供虚拟机级信任域保护,兼容性好且易于部署。文章结合金融与医疗行业实战案例,为开发者提供了清晰的选型指南,帮助根据代码可改性、安全需求、部署规模及生态成本选择最合适的机密计算方案。

java5的博客 420

ROS 2实战:用MoveIt Task Constructor让机械臂完成抓取任务(附避坑指南)

本文详细介绍了如何在ROS 2环境中使用MoveIt Task Constructor框架,为Franka Panda机械臂构建一个完整的拾取放置任务流水线。通过分解任务阶段、配置规划器并处理实际部署中的常见问题,帮助开发者从基础运动规划升级到可靠的多步骤任务编排,并附有核心避坑指南。

vvv99的博客 507

头歌实训 MySQL数据库 - 连接查询和子查询基础

第1关:内连接查询 任务描述 本关任务:使用内连接查询数据表中学生姓名和对应的班级。 编程要求 在右侧编辑器补充代码,查询数据表中学生姓名以及对应的班级名称,将其对应的列名分别另命名为studentName和className。

m0_73504458的博客 6903

ArcGIS+PLUS+InVEST三件套实战:从零搞定土地利用变化与碳储量预测(附完整数据包)

本文详细介绍了如何整合ArcGIS、PLUS模型和InVEST模型,构建土地利用变化与碳储量预测的完整研究流水线。通过多情景模拟和生态系统服务评估,提供从数据准备到结果验证的实战指南,助力研究者高效完成生态评估项目。

weixin_30399821的博客 543

GreatSQL是一个国内自主的开源数据库,可替代mysql

此外,GreatSQL社区还提供了MySQL Shell for GreatSQL,这是一个高级客户端和代码编辑器,支持JavaScript和Python脚本功能,以及与MySQL一起使用的API。它可以用来管理数据库,特别是对MGR的支持,可以方便地进行搭建、管理和配置。GreatSQL的架构可以分为连接层、服务层和存储引擎层。连接层负责与客户端建立连接,服务层是GreatSQL的核心,包括连接器、分析器、优化器、执行器等,而存储引擎层则负责数据的存储和提取。

地球空间 3193

解析 RABAX during SAPGUI Logon 错误及其解决方案

登录用户关联了初始启动程序,该程序由于未处理的异常导致运行时错误。在 ST22 查看错误的程序名和错误行。修复初始程序代码中的逻辑问题。重新部署修复后的代码。示例代码:防止未处理的异常TRY." 模拟逻辑处理ENDTRY.此代码通过 TRY-CATCH 块捕获潜在错误,避免程序崩溃。是 SAP 系统中常见的运行时错误,其根源可能涉及多个方面,包括用户配置、系统状态、数据库连接和自定义开发等。通过结合 ST22、SM21 等诊断工具,以及完善的代码实践和系统监控,可以有效预防和解决此类问题。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 1781

实战 | OpenCV实现扫描文本矫正应用与实现详解(附源码)

导读 本文主要介绍使用OpenCV对扫描文本矫正的应用实例及详细实现步骤。 背景介绍 在使用打印机或扫描仪扫描文档时,由于摆放位置差异难免造成扫描文档的倾斜。本文将使用OpenCV将倾斜的文档矫正水平并去除黑边。 实现步骤 本文只针对包含大部分文字的文档做倾斜矫正,思路来源是大部分文字倾斜后同一行的也在同一条直线,通过拟合直线计算文本倾斜角度,然后旋转来实现文本倾斜矫正。 详细步骤: ①加载倾斜图像 ②灰度转换+腐蚀+膨胀 ③Canny边缘检测 + 霍夫线变换检测直线 ...

Color Space的博客 3400

CentOS7安装GreatSQL

GreatSQL 数据库是一款 开源免费 数据库,可在普通硬件上满足金融级应用场景,具有 高可用、高性能、高兼容、高安全 等特性,可作为 MySQL 或 Percona Server for MySQL 的理想可选替换。

落的博客 1701

C#:实现统计图像主颜色的算法(附完整源码)

C#:实现统计图像主颜色的算法(附完整源码)

希望我的博客,能帮上你解决学习中工作中所遇到的问题 520

GreatSQL社区2024年全年总结(免费领红包封面)

* GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源。社区2024年总结GreatSQL 社区在2024年度上持续迈进,成果斐然。一方面,开放了 GreatSQL 单机版以及三节点 MGR 集群的在线测试体验环境,让用户能够在线体验各种 GreatSQL 创新特性。另一方面,社区手册也持续更新,方便用户查阅。同时,社区积极拓展教育合作领域,成功走进郑州大学,联合开设 “G...

老叶茶馆 195

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

图文结合带你搞懂GreatSQL体系架构

往期系列回顾很多小伙伴使用了GreatSQL,但是对GreatSQL的底层原理还不是很了解,今天就带大家一起揭开GreatSQL体系架构的神秘面纱!首先来回顾一张经典的体系架构图:图1_GreatSQL5.7 版本体系架构图由此可以发现,GreatSQL5.7 由以下几部分组成GreatSQL数据库区别于其他数据库的一个特点就是其可插拔的表存储引擎,特别需要注意的是,存储引擎是基于表的,而不是数据库。然而,经典同时也意味着这幅图已经相当陈旧了。在GreatSQL8.0 及更高版本中,查询缓存这一功能已经被移

GreatSQL2021的博客 569

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

MySQL开发技巧 - 分页和索引(一)

@R星校长 第1关:MySQL 分页查询 本关任务:能分页读取表中数据,针对大数据量进行简单优化。 如何根据页数和每页数据量进行分页查询; 大数据量级进行优化分页查询。 什么是分页查询 当一个表中有很多符合查询条件的数据的时候,我们往往不需要把他们全部一次性取出来,那样对查询效率或者服务器性能来说都会是一个极大的挑战:例如最简单的商城,假设商城中有一万个数据,但我们在前端可能只会每次看到一页10个左右的数据,当我们浏览完这十个商品后,点击下一页浏览其他的商品,这样的分页浏览,对实际存储商品数据的 My.

qq_44745905的博客 3423

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

MariaDB 和 GreatSQL 性能差异背后的真相

最近项目上遇到了两次 MariaDB 和 GreatSQL 的对比,GreatSQL受到客户质疑,最后经过排查抓到性能差异背后的真相。基于此做个分享。无论是问题一中的100倍性能背后还是插入hang住,其实背后都是对产品的不了解,MariaDB 10.3.39其实对应的是5.7的产品,而且其本身的默认参数调整有作弊嫌疑,默认关闭binlog ,sync_binlog设置为0,checkpoint阈值降低,提高checkpoint的频率等设置,面向测试环境数据是很好看的,但是增加了生产环境的风险和硬件成本。

GreatSQL2021的博客 1668

【GreatSQL优化器-01】const_table

GreatSQL的优化器主要用JOIN类来进行处理SQL语句的,JOIN类有以下四个table数量相关的成员变量。其中const_tables是optimize最开始就检查并且标识的,因为这样可以把记录最少的表放在执行计划的第一步,在后面的执行计划里面这些const tables是不参与循环遍历和计算的,因此可以减少很多开销。计数名称说明哪个函数进行累加tables该查询语句的所有表的数量,包含物化表和临时表该查询语句的主要表的数量,不包含物化表该查询语句中只有0行或者1行的表数量。

GreatSQL2021的博客 738

图文结合丨Prometheus+Grafana+GreatSQL性能监控系统搭建指南(上)

*GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源。一、环境介绍本文环境,以及本文所采用数据库为GreatSQL 8.0.32-24$cat/etc/system-release RedHatEnterpriseLinuxServerrelease7.9(Maipo) $uname-a Linuxgip3.10.0-1160.el7.x86_6...

老叶茶馆 336

图文解读MySQL/GreatSQL体系架构

*GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源。往期系列回顾图文结合系列之带你搞懂MySQL日志系列很多小伙伴使用了GreatSQL,但是对GreatSQL的底层原理还不是很了解,今天就带大家一起揭开GreatSQL体系架构的神秘面纱!首先来回顾一张经典的体系架构图:图1_GreatSQL5.7 版本体系架构图由此可以发现,GreatSQL5.7 由以下几部分组成连...

老叶茶馆 520

万里数据库GreatSQL监控解析

GreatSQL是MySQL的一个分支,专注于提升MGR(MySQL Group Replication)的可靠性及性能。乐维监控平台可以有效地监控GreatSQL,帮助用户及时发现并解决潜在的性能问题。通过在GreatSQL服务器上安装监控代理,收集数据库性能数据,进而配置监控项,配置需要监控的GreatSQL指标,再为关键性能指标设置告警阈值,在性能下降或出现问题时及时通知,即可实现对GreatSQL数据库的监控。

乐维社区的博客 1360

大数据量下数据库分页查询优化方案汇总

大数据量下数据库分页查询优化方案汇总

zhaoshuangjian 2348

MySQL大数据量分页性能优化

测试实验 1. 直接用limitstart,count分页语句,也是我程序中用的方法: select*fromproductlimitstart,count 当起始页较小时,查询没有性能问题,我们分别看下从10,100,1000,10000开始分页的执行时间(每页取20条),如下: select*fromproductlimit10,20 0.0...

10年老码农 550

GreatSQL 8.0.25-16初体验

*GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源。1. 准备工作1.1 下载RPM包1.2 准备YUM源2. 初始化安装2.1 各节点安装RPM包2.2 初始化Primary节点2.3 初始化Secondary 和 Arbitrator 节点3、搭建MGR集群体验GreatSQL 8.0.25-16各个新特性。在刚刚发布的GreatSQL 8.0.25-16中,主打以...

老叶茶馆 751

GreatSQL,打造更好的MGR生态

用GreatSQL,上MGR更放心!P.S,文末有彩蛋,别错过 :)在3月20日「3306π」社区成都站分享会上,万里数据库CTO娄帅做了主题分享《MGR Bug修复之路》。娄帅指出,由于...

老叶茶馆 608

GreatSQL MGR优化参考

0. 前言GreatSQL运行更平稳,不会有大的抖动。MySQL官方版本的MGR更适合在中小规模业务环境下运行。1. GreatSQL的优势GreatSQL的优势在于提升了MGR的性能及可...

老叶茶馆 1058
上一篇: 【GreatSQL优化器-02】索引和Sargable谓词
下一篇: 【GreatSQL优化器-04】贪婪搜索算法浅析
GreatSQL社区
博客等级 码龄5年 1210粉丝 390原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值