当前位置: 首页 > news >正文

数据类型相关问题导致的索引失效 | OceanBase SQL 优化实践

背景

针对在OceanBase 论坛中遇到的一些典型SQL调优问题,进行记录与总结,分享给大家。本文介绍的事3个场景:数据类型不匹配、字符集相关属性不匹配,和过滤/联接条件上包含系统函数。

场景一:数据类型不匹配

类型不匹配包括两方面:

  • 数据类型不匹配:比如 int vs varchar 等。
  • 数据精度(包含 precision、scale 等数据类型的附属属性)不匹配:比如 char(100) vs char(1)、decimal(5, 2) vs decimal(3, 1) 等。

接下来看一个数据类型不匹配的简单例子:

create table t1(c1 varchar(10) primary key);insert into t1 values('1'), ('01.0'), ('+1.0');select * from t1 where c1 = 1;
+------+
| c1   |
+------+
| +1.0 |
| 01.0 |
| 1    |
+------+-- sql 1
obclient> explain select * from t1 where c1 = 1;
+---------------------------------------------------------------------------------------------------+
| Query Plan                                                                                        |
+---------------------------------------------------------------------------------------------------+
| ===============================================                                                   |
| |ID|OPERATOR       |NAME|EST.ROWS|EST.TIME(us)|                                                   |
| -----------------------------------------------                                                   |
| |0 |TABLE FULL SCAN|t1  |1       |4           |                                                   |
| ===============================================                                                   |
| Outputs & filters:                                                                                |
| -------------------------------------                                                             |
|   0 - output([t1.c1]), filter([cast(t1.c1, DECIMAL(-1, -1)) = cast(1, DECIMAL(1, 0))]), rowset=16 |
|       access([t1.c1]), partitions(p0)                                                             |
|       is_index_back=false, is_global_index=false, filter_before_indexback[false],                 |
|       range_key([t1.c1]), range(MIN ; MAX)always true                                             |
+---------------------------------------------------------------------------------------------------+
11 rows in set (0.04 sec)

在上面的例子中,sql 1 的计划显示进行了全表扫描,没有使用索引:

  • 查询计划中的 range_key 为 t1.c1,由于 c1 是字符串类型,而 1 是整数类型,因此进行了隐性类型转换(Implicit cast)。
  • 转执行程中,系统会隐式地把 varchar 类型的 '+1.0' 被转换为 int 类型的 1,无法利用建在 varchar 上的索引进行 int 类型的定位。
  • 这个隐式类型转换方向是由 SQL 标准制定的,标准 SQL 定义的转换方向大致是:字符串类型 -> 数字类型 -> 时间类型

作为对比,下面 sql 2 的计划中,通过显式指定类型转换,从而可以达到利用索引进行TABLE GET的目的。(注意:这样改写 SQL 之后,和上面的 SQL 是不等价的,需要关注是否是业务可以接受的!)


-- sql 2
obclient> explain select * from t1 where c1 = cast(1 as char);
+----------------------------------------------------+
| Query Plan                                         |
+----------------------------------------------------+
| =========================================          |
| |ID|OPERATOR |NAME|EST.ROWS|EST.TIME(us)|          |
| -----------------------------------------          |
| |0 |TABLE GET|t1  |1       |3           |          |
| =========================================          |
| Outputs & filters:                                 |
| -------------------------------------              |
|   0 - output([t1.c1]), filter(nil), rowset=16      |
|       access([t1.c1]), partitions(p0)              |
|       is_index_back=false, is_global_index=false,  |
|       range_key([t1.c1]), range[1 ; 1],            |
|       range_cond([t1.c1 = cast(1, CHAR(1048576))]) |
+----------------------------------------------------+

为了方便大家理解,我们再反着来一遍,创建一个整数类型的列 c1,并尝试使用字符 '+1.0' 来查询。

create table t1(c1 int primary key);obclient> explain select * from t1 where c1 = '+1.0';
+--------------------------------------------------------------------------------+
| Query Plan                                                                     |
+--------------------------------------------------------------------------------+
| =========================================                                      |
| |ID|OPERATOR |NAME|EST.ROWS|EST.TIME(us)|                                      |
| -----------------------------------------                                      |
| |0 |TABLE GET|t1  |1       |5           |                                      |
| =========================================                                      |
| Outputs & filters:                                                             |
| -------------------------------------                                          |
|   0 - output([t1.c1]), filter(nil), rowset=16                                  |
|       access([t1.c1]), partitions(p0)                                          |
|       is_index_back=false, is_global_index=false,                              |
|       range_key([t1.c1]), range[1 ; 1],                                        |
|       range_cond([cast(t1.c1, DECIMAL(11, 0)) = cast('+1.0', DECIMAL(1, -1))]) |
+--------------------------------------------------------------------------------+
12 rows in set (0.04 sec)

在上面这个例子中,尽管我们使用了字符 '+1.0' 来查询整数类型的列 c1,查询计划仍然使用了索引扫描。这是因为索引建在整型列上,隐式类型转换会将字符 '+1.0' 转换为整数 1,转换之后正好可以利用到建在整数类型上的索引。

场景二:字符集相关属性不匹配

charset 或者 collation 不同,都会导致无法利用索引。

请大家直接参考上一篇博客《collation 导致的索引失效》,内容十分详实,所以这里不再赘述了。

场景三:过滤/联接条件上包含系统函数

创建如下的表和索引,索引建在 date 类型列上。

CREATE TABLE employees (employee_id INT PRIMARY KEY,hire_date DATE
);CREATE INDEX idx_hire_date ON employees(hire_date);

执行 SQL 时,如果在过滤条件中的 hire_dater 列的外层加一个 year 函数,就无法走上索引了。这个很好理解,索引建在 date 类型列上,但是过了条件两边,一个是 year,一个是 int,都不是 date 类型,走不上索引也是理所应当。

explain SELECT * FROM employees WHERE YEAR(hire_date) = 2023;
+---------------------------------------------------------------------------------------------------------------------+
| Query Plan                                                                                                          |
+---------------------------------------------------------------------------------------------------------------------+
| ====================================================                                                                |
| |ID|OPERATOR       |NAME     |EST.ROWS|EST.TIME(us)|                                                                |
| ----------------------------------------------------                                                                |
| |0 |TABLE FULL SCAN|employees|1       |4           |                                                                |
| ====================================================                                                                |
| Outputs & filters:                                                                                                  |
| -------------------------------------                                                                               |
|   0 - output([employees.employee_id], [employees.hire_date]), filter([year(employees.hire_date) = 2023]), rowset=16 |
|       access([employees.employee_id], [employees.hire_date]), partitions(p0)                                        |
|       is_index_back=false, is_global_index=false, filter_before_indexback[false],                                   |
|       range_key([employees.employee_id]), range(MIN ; MAX)always true                                               |
+---------------------------------------------------------------------------------------------------------------------+
11 rows in set (0.005 sec)

这个时候,有一些用户会尝试用 hint 强制让 SQL 走索引,不过类型不匹配,索引无能为力,最终依然走不上索引。

explain basic SELECT /* index(employees idx_hire_date) */ * FROM employees WHERE year(hire_date) = 2023;
+---------------------------------------------------------------------------------------------------------------------+
| Query Plan                                                                                                          |
+---------------------------------------------------------------------------------------------------------------------+
| ==============================                                                                                      |
| |ID|OPERATOR       |NAME     |                                                                                      |
| ------------------------------                                                                                      |
| |0 |TABLE FULL SCAN|employees|                                                                                      |
| ==============================                                                                                      |
| Outputs & filters:                                                                                                  |
| -------------------------------------                                                                               |
|   0 - output([employees.employee_id], [employees.hire_date]), filter([year(employees.hire_date) = 2023]), rowset=16 |
|       access([employees.employee_id], [employees.hire_date]), partitions(p0)                                        |
|       is_index_back=false, is_global_index=false, filter_before_indexback[false],                                   |
|       range_key([employees.employee_id]), range(MIN ; MAX)always true                                               |
+---------------------------------------------------------------------------------------------------------------------+
11 rows in set (0.05 sec)

这种场景,最简单的等价 SQL 改写方法,就是让过滤条件中出现索引列的 date 类型,例如:

explain SELECT * FROM employees WHERE hire_date BETWEEN '2023-01-01' AND '2023-12-31';
+-----------------------------------------------------------------------------------------------------------------------------------------------------------+
| Query Plan                                                                                                                                                |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------+
| ====================================================================                                                                                      |
| |ID|OPERATOR        |NAME                    |EST.ROWS|EST.TIME(us)|                                                                                      |
| --------------------------------------------------------------------                                                                                      |
| |0 |TABLE RANGE SCAN|employees(idx_hire_date)|1       |4           |                                                                                      |
| ====================================================================                                                                                      |
| Outputs & filters:                                                                                                                                        |
| -------------------------------------                                                                                                                     |
|   0 - output([employees.employee_id], [employees.hire_date]), filter(nil), rowset=16                                                                      |
|       access([employees.employee_id], [employees.hire_date]), partitions(p0)                                                                              |
|       is_index_back=false, is_global_index=false,                                                                                                         |
|       range_key([employees.hire_date], [employees.employee_id]), range(2023-01-01,MIN ; 2023-12-31,MAX),                                                  |
|       range_cond([cast(employees.hire_date, DATETIME(-1, -1)) >= INTERNAL_FUNCTION('2023-01-01', 114, 17)], [cast(employees.hire_date, DATETIME(-1, -1))  |
|       <= INTERNAL_FUNCTION('2023-12-31', 112, 17)])                                                                                                       |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------+
13 rows in set (0.003 sec)

最后再多说一句,如果在过滤/联接条件的列上,加了计算结果类型和索引列类型一样的系统函数,也会导致走不上索引。例如:

create table t1(c1 int, index idx(c1));-- 走上索引了
obclient [test]> explain select * from t1 where c1 = 1;
+-----------------------------------------------------------------------+
| Query Plan                                                            |
+-----------------------------------------------------------------------+
| ===================================================                   |
| |ID|OPERATOR        |NAME   |EST.ROWS|EST.TIME(us)|                   |
| ---------------------------------------------------                   |
| |0 |TABLE RANGE SCAN|t1(idx)|1       |4           |                   |
| ===================================================                   |
| Outputs & filters:                                                    |
| -------------------------------------                                 |
|   0 - output([t1.c1]), filter(nil), rowset=16                         |
|       access([t1.c1]), partitions(p0)                                 |
|       is_index_back=false, is_global_index=false,                     |
|       range_key([t1.c1], [t1.__pk_increment]), range(1,MIN ; 1,MAX),  |
|       range_cond([t1.c1 = 1])                                         |
+-----------------------------------------------------------------------+
12 rows in set (0.013 sec)-- 过滤条件在列上加了个 add 函数,就走不上索引
explain select * from t1 where c1 + 1 = 1;
+------------------------------------------------------------------------------------+
| Query Plan                                                                         |
+------------------------------------------------------------------------------------+
| ===============================================                                    |
| |ID|OPERATOR       |NAME|EST.ROWS|EST.TIME(us)|                                    |
| -----------------------------------------------                                    |
| |0 |TABLE FULL SCAN|t1  |1       |4           |                                    |
| ===============================================                                    |
| Outputs & filters:                                                                 |
| -------------------------------------                                              |
|   0 - output([t1.c1]), filter([t1.c1 + 1 = 1]), rowset=16                          |
|       access([t1.c1]), partitions(p0)                                              |
|       is_index_back=false, is_global_index=false, filter_before_indexback[false],  |
|       range_key([t1.__pk_increment]), range(MIN ; MAX)always true                  |
+------------------------------------------------------------------------------------+
11 rows in set (0.002 sec)

原因是优化器在抽 query range 的时候,range_key 上不能有函数。不然每一行在函数作用下的结果可能都是不连续的,就构不成 range 了。

总结

  1. 当 SQL 走不上索引时,需要注意索引条件上是否存在隐式 cast,并考虑能否通过显式指定 cast 或其他 SQL 改写的方式解决该问题。
  2. 尽量保证索引条件上 column 属性和索引列完全一致,包括数据类型、字符集属性(charset 和 collation)、精度(precision 和 scale)等。
  3. 尽量不要在过滤条件和联接条件里,对希望能走索引的列上加系统函数。可以考虑通过改写 SQL 解决该问题。

补充

针对性能调优的各种场景,在OceanBas社区中建立了一个《OceanBase 性能调优》博客专题,欢迎大家积极留言评论,提出您的问题和需求。

相关文章:

数据类型相关问题导致的索引失效 | OceanBase SQL 优化实践

背景 针对在OceanBase 论坛中遇到的一些典型SQL调优问题&#xff0c;进行记录与总结&#xff0c;分享给大家。本文介绍的事3个场景&#xff1a;数据类型不匹配、字符集相关属性不匹配&#xff0c;和过滤/联接条件上包含系统函数。 场景一&#xff1a;数据类型不匹配 类型不匹…...

银行卡风险画像在社交行业网络安全的应用

据中国支付清算协会统计&#xff0c;2023年银行卡欺诈案件造成的经济损失同比增长21%&#xff0c;而社交平台中超过35%的诈骗行为涉及金融账户盗用。本文将讲述如何使用风险画像技术助力社交网络安全。 银行卡风险画像的核心逻辑 银行卡风险画像是通过多维度数据分析构建的用…...

C++程序设计基础实验:C++对C的扩展特性与应用

C程序设计基础实验&#xff1a;C对C的扩展特性与应用 &#x1f525; 本文详细讲解C基础实验&#xff0c;包含C对C语言的扩充与增强特性&#xff0c;从零开始掌握函数重载、引用、指针等核心概念&#xff0c;附详细代码分析与运行结果。适合C初学者和有C语言基础想学习C的同学&a…...

极狐GitLab 外部授权控制机制是怎样的?

极狐GitLab 是 GitLab 在中国的发行版&#xff0c;关于中文参考文档和资料有&#xff1a; 极狐GitLab 中文文档极狐GitLab 中文论坛极狐GitLab 官网 外部授权控制 (BASIC SELF) 在高度控制的环境中&#xff0c;访问策略可能需要由外部服务控制&#xff0c;该服务允许基于项目…...

告别Feign:基于Spring 6.1 RestClient构建高可用声明式HTTP客户端

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;精通Java编…...

极狐GitLab 项目和群组的导入导出速率限制如何设置?

极狐GitLab 是 GitLab 在中国的发行版&#xff0c;关于中文参考文档和资料有&#xff1a; 极狐GitLab 中文文档极狐GitLab 中文论坛极狐GitLab 官网 项目和群组的导入导出速率限制 (BASIC SELF) 您可以为项目和群组的导入和导出配置速率限制&#xff1a; 更改速率限制&#…...

中华传承-医山命相卜-铁板神数

铁板神数 子平法 子平法 徐子平 倪海夏 一月&#xff08;公历2025年1月29日-2025年2月27日&#xff09; 运势&#xff1a;事业开局不利&#xff0c;难以快速适应工作节奏&#xff0c;可能面临上级的质疑或竞争压力。财富方面容易财来财去&#xff0c;需留意理财陷阱。 原因&…...

C++学习:六个月从基础到就业——面向对象编程:接口设计

C学习&#xff1a;六个月从基础到就业——面向对象编程&#xff1a;接口设计 本文是我C学习之旅系列的第十五篇技术文章&#xff0c;重点讨论在C中进行接口设计的原则、技术和最佳实践。查看完整系列目录了解更多内容。 引言 在面向对象的软件开发中&#xff0c;良好的接口设计…...

工作总结(十二)——迁移svn单项目到gitlab上,保留历史提交记录

文章目录 前言一、目的二、操作步骤1.创建项目库2.复制历史提交者账号3.复制待迁移项目以及历史记录4.push到gitlab远程仓库 总结 前言 本系列文章主要记录工作中一些需要记录的内容 一、目的 因为一些原因&#xff0c;我需要将svn库上的某个项目迁移到公司的gitlab库管理平台…...

PS中制作一张扣洞贴图

要在PS制作如下一张贴图&#xff0c;如下图所示 步骤&#xff1a; 1.首先复制一张图层 2.将最底层图层的透明度调整为0 3.选择画笔的模式为清除 4.设置画笔大小 5.选中需要清除的图层&#xff0c;然后就可以将图层的像素点清除了 6.导出成PNG文件即可 注&#xff1…...

STM32 HAL库 Freertos创建多任务

1. 引言 STM32F407 是 ST 公司推出的一款高性能微控制器&#xff0c;具有丰富的外设资源和强大的处理能力。HAL&#xff08;Hardware Abstraction Layer&#xff09;库是 ST 为其微控制器提供的硬件抽象层&#xff0c;它简化了硬件操作&#xff0c;提高了开发效率。FreeRTOS 是…...

android测试硬件工具 安卓硬件测试命令

Android开发常用ADB命令大全 在Android开发过程中&#xff0c;ADB(Android Debug Bridge)是一个非常重要的调试工具。掌握这些命令可以大大提高开发效率。如果你正在使用克魔开发助手(Keymob)这样的开发工具&#xff0c;你会发现它已经集成了很多ADB功能&#xff0c;让调试变得…...

第12篇:Linux程序访问控制FPGA端Switch<一>

Q&#xff1a;如何写.c代码访问读取FPGA端的滑动开关SW的值&#xff1f; A&#xff1a;DE1-SoC开发板上有10个滑动开关连接到DE1_SoC_Computer系统的并行输入端口&#xff0c;该端口只有一个10位只读Data寄存器映射到地址0xFF200040&#xff0c;对Data寄存器进行读操作并将读出…...

硬盘变废为宝!西部数据携微软等启动稀土回收 效率可达90%

快科技4月18日消息&#xff0c;西部数据&#xff08;Western Digital&#xff09;宣布&#xff0c;与微软、Critical Materials Recycling及PedalPoint Recycling携手&#xff0c;在美国启动一项跨产业前导计划-稀土回收。 目前&#xff0c;西部数据已经成功从报废硬盘&#x…...

元宇宙概念兴起,B 端数字孪生迎来哪些新机遇?

在科技飞速发展的当下&#xff0c;元宇宙概念如同一颗璀璨新星&#xff0c;迅速吸引了全球的目光。随着元宇宙的兴起&#xff0c;与之紧密相关的 B 端数字孪生技术也迎来了前所未有的发展机遇。元宇宙与 B 端数字孪生的融合&#xff0c;正悄然改变着多个行业的运作模式&#xf…...

用 NLP + Streamlit,把问卷变成能说话的反馈

网罗开发 &#xff08;小红书、快手、视频号同名&#xff09; 大家好&#xff0c;我是 展菲&#xff0c;目前在上市企业从事人工智能项目研发管理工作&#xff0c;平时热衷于分享各种编程领域的软硬技能知识以及前沿技术&#xff0c;包括iOS、前端、Harmony OS、Java、Python等…...

stl 容器 – map

stl 容器 – map 1. map 和 multimap的使用文档 参考文档 参考文档点这里哟 &#x1f308; &#x1f618; 2. map 类的介绍 map的声明如下 template < class Key, // map::key_type class T, // map::mapped_type class Compare less<Key>, // map::key_…...

20250417-vue-动态插槽名

动态指令参数在 v-slot 上也是有效的&#xff0c;即可以定义下面这样的动态插槽名&#xff1a; <base-layout><template v-slot:[dynamicSlotName]>...</template><!-- 缩写为 --><template #[dynamicSlotName]>...</template> </base…...

010301-cdn_waf-web扩展1-基础入门-网络安全

文章目录 1 WAF1.1WAF 的核心功能1.2 WAF 的部署类型1.3 WAF 的应用场景1.4 主流 WAF 产品1.5 如何选择 WAF&#xff1f;1.6 注意事项1.7 waf总结和演示 2 CDN2.1 核心原理2.2 关键功能2.3 典型应用场景2.4 优势2.5 主流CDN服务商2.6 技术实现2.7 注意事项2.8cdn安全测试和演示…...

CentOS7执行yum命令报错 Could not retrieve mirrorlist http://mirrorlist.centos.org

CentOS7执行yum命令报错 引更新yum源备份原有源创建新的源文件清理并重建缓存 引 CentOS 7 系统无法连接到 CentOS 的官方镜像站点。这通常是由于网络问题或 CentOS 7 已停止维护导致的&#xff08;2024年6月30日后 CentOS 7 已进入 EOL&#xff09; 报错明细&#xff1a; 已…...

在阿里云虚拟主机上启用WordPress伪静态

在阿里云虚拟主机上启用WordPress伪静态&#xff0c;需要根据虚拟主机的Web服务器类型(Nginx或Apache)进行相应的设置。以下是具体步骤&#xff1a; 1. 确认虚拟主机的Web服务器类型 登录阿里云虚拟主机管理控制台。 查看主机的配置信息&#xff0c;确认是使用Nginx还是Apac…...

【java 13天进阶Day06】Map集合,HashMapTreeMap,斗地主、图书管理系统,排序算法

Map集合 Collection是单值集合体系。 Map集合是另一个集合体系&#xff0c;是一种双列集合&#xff0c;每个元素包含两个值。 Map集合的每个元素的格式&#xff1a;keyvalue(键值对元素)。 Map集合也被称为“键值对集合”。 Map集合的完整格式&#xff1a;{key1value1 , ke…...

从代码学习深度学习 - 小批量随机梯度下降 PyTorch 版

文章目录 前言一、数据准备与处理1.1 数据集简介1.2 数据加载与预处理二、训练工具与辅助类三、可视化工具四、模型训练五、执行训练总结前言 深度学习是人工智能领域的核心技术之一,而小批量随机梯度下降(Mini-Batch Stochastic Gradient Descent, SGD)是训练神经网络的基…...

03、GPIO外设(三):标准库代码示例

标准库代码示例 1、点亮LED2、LED闪烁3、LED流水灯4、按键控制LED5、蜂鸣器 本章源代码链接&#xff1a; 链接: link 1、点亮LED 实验要求&#xff1a;点亮LED ①LED.c文件的代码如下: #include "LED.h"/*** LED引脚初始化*//* 定义数组&#xff0c;想要添加引脚…...

PyTorch 深度学习实战(37):分布式训练(DP/DDP/Deepspeed)实战

在上一篇文章中&#xff0c;我们探讨了混合精度训练与梯度缩放技术。本文将深入介绍分布式训练的三种主流方法&#xff1a;Data Parallel (DP)、Distributed Data Parallel (DDP) 和 DeepSpeed&#xff0c;帮助您掌握大规模模型训练的关键技术。我们将使用PyTorch在CIFAR-10分类…...

MCP系列之架构篇:深入理解MCP的设计架构

前言 在上一篇《MCP系列之基础篇》中,我们初步了解了MCP(模型上下文协议)的基本概念和价值。本篇文章将深入探讨MCP的技术架构,帮助开发者和技术爱好者更全面地理解这一协议的内部工作机制。我们将剖析MCP的核心组件、通信模型和工作流程,解析Host、Client和Server三者之…...

RT-Thread RTThread studio 初使用

RT-Thread Studio 下载 https://www.rt-thread.org/studio.html 安装使用 https://bbs.elecfans.com/jishu_2425653_1_1.html 4 编译问题解决 问题一&#xff1a;error: unknown type name clock_t 具体的类型值是在sys/_types.h中定义的&#xff0c;需要包含sys/_types.h 这个…...

设计模式 --- 外观模式

外观模式是一种结构型设计模式&#xff0c;为复杂子系统提供​​统一的高层接口​​&#xff0c;通过定义一个外观类来​​简化客户端与子系统的交互​​&#xff0c;降低系统耦合度。这种模式隐藏了子系统的复杂性&#xff0c;将客户端与子系统的实现细节隔离开来&#xff0c;…...

第十二节:原理深挖-React Fiber架构核心思想

链表结构、时间切片&#xff08;Time Slicing&#xff09; 优先级调度实现&#xff08;如用户输入>网络请求&#xff09; React Fiber架构深度解析&#xff1a;从链表到优先级调度的革命性升级 一、Fiber架构核心设计思想 React Fiber是React 16的底层协调算法重构&#x…...

利用DeepSeek设计一个HTML批量转换工具设计

需求词&#xff1a;需要设计一个能够批量转换HTML文件格式的网页在线工具&#xff0c;界面简洁易用 功能概述 设计一个网页在线工具&#xff0c;允许用户批量上传HTML文件并进行格式转换&#xff0c;包括&#xff1a; HTML美化/格式化 HTML压缩/最小化 HTML到XHTML转换 HT…...

TypeScript 从入门到精通:完整教程与实战应用(一)

1. TypeScript 简介 什么是 TypeScript&#xff1f; TypeScript 是 JavaScript 的超集&#xff0c;添加了静态类型系统&#xff0c;由微软开发并开源。它编译成纯 JavaScript 运行在任何 JavaScript 环境中。 为什么使用 TypeScript&#xff1f; 类型安全&#xff1a;在编译时…...

什么是Python单例模式

什么是Python单例模式 Python单例模式是一种创建型设计模式,目的是确保一个类仅有一个实例,并提供一个全局访问点来获取该实例。以下从作用和示例进行介绍: 作用 控制资源使用:避免对系统资源的重复消耗,像数据库连接、文件句柄等稀缺资源,只创建一个实例来管理使用,防…...

PHP8.2.9NTS版本使用composer报错,扩展找不到的问题处理

使用composer install时报错&#xff1a; The openssl extension is required for SSL/TLS protection but is not available. If you can not enable the openssl extension, you can disable this error, at y our own risk, by setting the ‘disable-tls’ option to true.…...

memcache使用

Memcache 是一款高性能的分布式内存对象缓存系统&#xff0c;以下是其使用方法&#xff1a; 安装与配置 • 安装 Memcached &#xff1a;在 CentOS 7 系统中&#xff0c;可使用命令sudo yum install memcached进行安装&#xff0c;也可从源码编译安装&#xff0c;如下载 memca…...

旅游资源网站登录(jsp+ssm+mysql5.x)

旅游资源网站登录(jspssmmysql5.x) 旅游资源网站是一个为旅游爱好者提供全面服务的平台。网站登录界面简洁明了&#xff0c;用户可以选择以管理员或普通用户身份登录。成功登录后&#xff0c;用户可以访问个人中心&#xff0c;进行修改密码和个人信息管理。用户管理模块允许管…...

Nacos 中使用了哪些缓存?缓存的目的是什么?是如何实现的?

Nacos 在服务端和客户端都广泛的使用了缓存机制&#xff0c;下面着重介绍一下。 一、 Nacos 服务端缓存 (Server-Side Caching) Nacos 服务端缓存的主要目的是提高读取性能、降低对底层存储&#xff08;数据库或磁盘文件&#xff09;的压力&#xff0c;并加速对客户端请求的响…...

「GitHub热榜」AIGC系统源码:AI问答+绘画+PPT+音乐生成一站式

—零门槛搭建私有化AI内容工厂&#xff0c;源码开放商业落地指南 为什么全栈AIGC系统成为企业刚需&#xff1f; 1. 传统方案的致命缺陷 痛点 使用ChatGPTMidjourneyCanva 本全栈方案 工具割裂 需切换5平台 一个系统全搞定 成本 年费50万 一次部署永久免费 数据安全 …...

Dify LLM大模型参数(一)

深入了解大语言模型&#xff08;LLM&#xff09;的参数设置 模型的参数对模型的输出效果有着至关重要的影响。不同的模型会拥有不同的参数&#xff0c;而这些参数的设置将直接影响模型的生成结果。以下是 DeepSeek 模型参数的详细介绍&#xff1a; 温度&#xff08;Tempera…...

快速使用工具Cursor

Cursor 是一款面向开发者的集成开发环境&#xff0c;用途如下&#xff1a; 代码编写&#xff1a;支持多语言&#xff0c;有语法高亮、智能补全与格式化功能。代码生成&#xff1a;能依据自然语言描述生成代码。协作开发&#xff1a;支持多人实时协作编辑项目。调试程序&#x…...

JVM之经典垃圾回收器

一、垃圾回收算法 1. 标记-清除&#xff08;Mark-Sweep&#xff09; 步骤&#xff1a; 标记&#xff1a;遍历对象图&#xff0c;标记所有存活对象。清除&#xff1a;回收未被标记的垃圾对象。 特点&#xff1a;简单&#xff0c;但会产生内存碎片。 2. 标记-复制&#xff08;…...

【“星瑞” O6 评测】—NPU 部署 face parser 模型

前言 瑞莎星睿 O6 (Radxa Orion O6) 拥有高达 28.8TOPs NPU (Neural Processing Unit) 算力&#xff0c;支持 INT4 / INT8 / INT16 / FP16 / BF16 和 TF32 类型的加速。这里通过通过官方的工具链进行FaceParsingBiSeNet的部署 1. FaceParsingBiSeNet onnx 推理 首先从百度网盘…...

hadoop的三大结构及其各自的作用

Hadoop 主要有三大核心组件&#xff0c;分别是 HDFS&#xff08;Hadoop Distributed File System&#xff09;、MapReduce 和 YARN&#xff0c;以下是它们各自的作用&#xff1a; HDFS&#xff08;Hadoop Distributed File System&#xff09; 存储数据&#xff1a;HDFS 是一个…...

免费将静态网站部署到服务器方法(仅支持HTML,CSS,JS)

原视频链接&#xff1a;把HTML免费部署到网站上&#xff0c;实现别人也能访问的教程来啦QAQ_哔哩哔哩_bilibili 注意&#xff1a;仅支持HTML、CSS、JS。不支持Vue等框架。 1.打开网站www.wordpress.org 点击红框按钮 点击红框按钮下载wordpress模板文件并解压。 将自己编写的…...

2、SpringAI接入ChatGPT与微服务整合

2、SpringAI接入ChatGPT与微服务整合 小薛博客AI 大模型资料 1、SpringAI简介 https://spring.io/projects/spring-ai Spring AI是一个人工智能工程的应用框架。其目标是将Spring生态系统的设计原则&#xff08;如可移植性和模块化设计&#xff09;应用于人工智能领域&#…...

6.7.图的深度优先遍历(英文缩写DFS)

树是特殊的图&#xff0c;没有回路的图就是树 BFS与DFS的区别在于&#xff0c;BFS使用了队列&#xff0c;DFS使用了栈 一.深度优先遍历&#xff1a; 1.树的深度优先遍历&#xff1a; 树的深度优先遍历分为先根遍历和后根遍历。 以树的先根遍历为例&#xff1a; 上述图片里…...

若依同步企业微信架构及ACTIVITI

企业微信配置 1.进入企业微信后台管理应用管理&#xff0c;新建应用 2.配置网页授权及JS-SDK 将验证文件下载到项目的pubilc下 启动项目 npm run dev 然后验证域名归属 3.配置企业可信IP 公网IP地址即可&#xff0c;仅此IP的服务可调用企业微信接口信息 4.构造域名回调域&a…...

PyTorch分布式训练调试方法(跟踪调用过程)

PyTorch分布式训练调试方法(跟踪调用过程) 背景 在分布式深度学习训练场景中,通信操作(如AllReduce、Send/Recv)和CUDA操作的时序问题往往难以调试。本工具通过以下方式提供调试支持: 拦截所有PyTorch张量操作并记录调用栈监控分布式通信操作的完整生命周期自动生成带时间…...

跟我学C++中级篇——内存异常的分析

一、内存问题引发的现象 在实际使用电脑过程中&#xff0c;经常会遇到电脑卡住了&#xff0c;鼠标和键盘也没反应。这时候儿会怎么办&#xff1f;其实此时打开任务管理器&#xff0c;就可以发现&#xff0c;有几种情况&#xff1a;一是CPU占用过高&#xff1b;二是IO占用过高&…...

HTML新标签与核心 API 实战

HTML5 新标签与核心 API 实战 引言 今天咱们来看看HTML5 新标签以及一些核心 API。 HTML5 的引入彻底改变了 Web 前端开发格局&#xff0c;尤其是其新增的多媒体和交互能力标签。对于前端开发者而言&#xff0c;理解并掌握 <video>、<audio>、<canvas> 和…...

vscode 红色波浪线问题

VSCode 红色波浪线问题终极解决方案 问题描述 在编写 C 项目时&#xff0c;CMake 编译通过但代码出现红色波浪线&#xff0c;常见问题&#xff1a; #include 提示找不到头文件枚举或类型名未定义成员函数或变量无法识别 这些是 VSCode 的 IntelliSense 配置问题&#xff0c…...