GreatSQL 在SQL中使用 HINT 语法修改会话变量
GreatSQL 在SQL中使用 HINT 语法修改会话变量
在 GreatSQL 支持一种新的优化Hint,名字叫SET_VAR,这个特性支持用户在查询语句里修改 GreatSQL 数据库的一些会话变量,当然修改只是对当前查询会话生效,不会影响到其他会话。
SET_VAR语法
SET_VAR这个hint用于临时设置系统变量的会话值(在单个语句的持续时间内有效)
SET_VAR的用法: SET_VAR(
var_name
=
value
)
var_name 是被临时修改的会话变量名,value是会话变量的取值
greatsql> SELECT @@unique_checks;SELECT /*+ SET_VAR(unique_checks=OFF) */ @@unique_checks;SELECT @@unique_checks; SELECT /*+ SET_VAR(sort_buffer_size = 16M) */ name FROM people ORDER BY name; INSERT /*+ SET_VAR(foreign_key_checks=OFF) */ INTO t2 VALUES(2); SELECT /*+ SET_VAR(optimizer_switch = 'mrr_cost_based=off') */ 1;
GreatSQL 8.0 之前的操作方法
在GreatSQL 8.0 之前要对一个查询进行会话变量修改,需要怎么操作:
1.查询之前的系统变量
greatsql> SELECT @@optimizer_switch;
2.备份系统变量
greatsql> SET @old_optimizer_switch = @@optimizer_switch;
3.设置新的变量
greatsql> SET optimizer_switch='index_merge=off';
4.运行查询语句
greatsql> SELECT empno,ename,deptno from emp limit 1;
5.恢复之前的系统变量
greatsql> SET optimizer_switch = @old_optimizer_switch;
是不是有点繁琐,现在我们使用SET_VAR这个新特性,很方便的就可以做这个操作了。
GreatSQL 8.0的操作方法
greatsql>explain SELECT empno,ename,deptno FROM emp WHERE deptno=10 or ename='CLARK'; +----+-------------+-------+------------+-------------+------------------+------------------+---------+------+------+----------+--------------------------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+-------------+------------------+------------------+---------+------+------+----------+--------------------------------------------+ | 1 | SIMPLE | emp | NULL | index_merge | deptno,idx_ename | deptno,idx_ename | 5,63 | NULL | 4 | 100.00 | Using union(deptno,idx_ename); Using where | +----+-------------+-------+------------+-------------+------------------+------------------+---------+------+------+----------+--------------------------------------------+ 1 row in set, 1 warning (0.01 sec)
从执行计划上看,SQL语句使用了索引合并(type=index_merge),如果不想该sql使用索引合并,则可以通过SET_VAR进行控制。
greatsql>explain SELECT /*+ SET_VAR(optimizer_switch='index_merge=off') */ empno,ename,deptno FROM emp WHERE deptno=10 or ename='CLARK'; +----+-------------+-------+------------+------+------------------+------+---------+------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+------+------------------+------+---------+------+------+----------+-------------+ | 1 | SIMPLE | emp | NULL | ALL | deptno,idx_ename | NULL | NULL | NULL | 14 | 38.10 | Using where | +----+-------------+-------+------------+------+------------------+------+---------+------+------+----------+-------------+ 1 row in set, 1 warning (0.00 sec
这个新特性是不是很方便呢,之前由于优化器的某些设置,少量sql语句选择了错误的执行计划,导致查询语句性能低下,又不能随意更改线上数据库的变量,有了SET_VAR这个新特性,对于这种情况,可以考虑在查询语句中使用set_var优化这条语句。
我们知道,使用hash jion时,会使用到join buffer,join buffer的大小由join_buffer_size控制,其默认值为256k,哈希连接不能使用超过此数量的内存。当哈希连接所需的内存超过可用量时,GreatSQL将使用磁盘上的文件来处理此问题,使用到了磁盘文件,性能会下降,如果只想针对单条语句设置join buffer就可以使用SET_VAR。
CREATE TABLE t1 (c1 INT, c2 INT); CREATE TABLE t2 (c1 INT, c2 INT); CREATE TABLE t3 (c1 INT, c2 INT);
分别对t1,t2,t3 插入100万,200万,300万数据
greatsql> SET @@cte_max_recursion_depth = 99999999; greatsql> INSERT INTO t1 WITH recursive t AS ( SELECT 1 AS c1 ,1 AS c2 UNION ALL SELECT t.c1+1,t.c1*2 FROM t WHERE t.c1 <1000000 ) SELECT * FROM t; Query OK, 1000000 rows affected (10.63 sec) Records: 1000000 Duplicates: 0 Warnings: 0 greatsql> SELECT @@join_buffer_size; +--------------------+ | @@join_buffer_size | +--------------------+ | 262144 | +--------------------+ 1 row in set (0.00 sec) greatsql> SELECT * FROM t1 JOIN t2 ON (t1.c1 = t2.c1 AND t1.c2 < t2.c2) JOIN t3 ON (t2.c1 = t3.c1); Empty set (6.91 sec) greatsql> SELECT /*+ SET_VAR(join_buffer_size=16777216) */ * FROM t1 JOIN t2 ON (t1.c1 = t2.c1 AND t1.c2 < t2.c2) JOIN t3 ON (t2.c1 = t3.c1); Empty set (5.87 sec)
注意事项
1、并非所有会话变量都允许与SET_VAR一起使用。如果设置不支持用SET_VAR更改的系统变量,则会出现警告。
greatsql> SELECT /*+ SET_VAR(collation_server = 'utf8mb4') */ 1; +---+ | 1 | +---+ | 1 | +---+ 1 row in set, 1 warning (0.01 sec) greatsql> SHOW WARNINGS\G *************************** 1. row *************************** Level: Warning Code: 3637 Message: Variable 'collation_server' cannot be set using SET_VAR hint. 1 row in set (0.00 sec)
2、SET_VAR语法只允许设置单个变量,但可以给出多个提示来设置多个变量:
SELECT /*+ SET_VAR(optimizer_switch = 'mrr_cost_based=off') SET_VAR(max_heap_table_size = 1G) */ 1;
3、如果没有这个系统变量或变量值不正确,则忽略SET_VAR提示并发出警告
SELECT /*+ SET_VAR(max_size = 1G) */ 1; SELECT /*+ SET_VAR(optimizer_switch = 'mrr_cost_based=yes') */ 1;
第1条语句没有 max_size 这个变量,语句2 的mrr_cost_based= on或者off, 企图将其设置为 yes是错误的,这两个语句的 hint 都会被忽略,并产生一个warning。
greatsql> SELECT /*+ SET_VAR(max_size = 1G) */ 1; +---+ | 1 | +---+ | 1 | +---+ 1 row in set, 1 warning (0.00 sec) greatsql> show warnings; +---------+------+---------------------------------------------+ | Level | Code | Message | +---------+------+---------------------------------------------+ | Warning | 3128 | Unresolved name 'max_size' for SET_VAR hint | +---------+------+---------------------------------------------+ 1 row in set (0.00 sec) greatsql> SELECT /*+ SET_VAR(optimizer_switch = 'mrr_cost_based=yes') */ 1; +---+ | 1 | +---+ | 1 | +---+ 1 row in set, 1 warning (0.00 sec) greatsql> show warnings; +---------+------+-------------------------------------------------------------------------------+ | Level | Code | Message | +---------+------+-------------------------------------------------------------------------------+ | Warning | 1231 | Variable 'optimizer_switch' can't be set to the value of 'mrr_cost_based=yes' | +---------+------+-------------------------------------------------------------------------------+ 1 row in set (0.00 sec)
4、SET_VAR提示只允许在语句级别使用。如果在子查询中使用,则会被忽略并给出警告。
复制会忽略复制语句中的SET_VAR,以避免潜在的安全问题。
SET_VAR支持的变量
SET_VAR只是对部分变量可以用的,整理了GreatSQL主要支持的变量供参考:
- bulk_insert_buffer_size
- default_table_encryption
- default_tmp_storage_engine
- div_precision_increment
- end_markers_in_json
- eq_range_index_dive_limit
- foreign_key_checks
- group_concat_max_len
- internal_tmp_mem_storage_engine
- join_buffer_size
- lock_wait_timeout
- max_error_count
- max_execution_time
- max_heap_table_size
- max_join_size
- max_length_for_sort_data
- max_points_in_geometry
- max_seeks_for_key
- max_sort_length
- optimizer_prune_level
- optimizer_search_depth
- optimizer_switch
- optimizer_trace_max_mem_size
- range_alloc_block_size
- read_buffer_size
- read_rnd_buffer_size
- secondary_engine_cost_threshold
- select_into_buffer_size
- select_into_disk_sync
- select_into_disk_sync_delay
- show_create_table_skip_secondary_engine
- sort_buffer_size
- sql_auto_is_null
- sql_big_selects
- sql_buffer_result
- sql_mode
- sql_require_primary_key
- sql_safe_updates
- sql_select_limit
- time_zone (≥ 8.0.17)
- timestamp
- tmp_table_size
- unique_checks
- updatable_views_with_limit
- use_secondary_engine
- windowing_use_high_precision
参考文档
-
https://dev.mysql.com/doc/refman/8.0/en/optimizer-hints.html#optimizer-hints-set-var
-
https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html
Enjoy GreatSQL :)
关于 GreatSQL
GreatSQL是适用于金融级应用的国内自主开源数据库,具备高性能、高可靠、高易用性、高安全等多个核心特性,可以作为MySQL或Percona Server的可选替换,用于线上生产环境,且完全免费并兼容MySQL或Percona Server。
相关链接: GreatSQL社区 Gitee GitHub Bilibili
GreatSQL社区:
社区有奖建议反馈: https://greatsql.cn/thread-54-1-1.html
社区博客有奖征稿详情: https://greatsql.cn/thread-100-1-1.html
(对文章有疑问或者有独到见解都可以去社区官网提出或分享哦~)
技术交流群:
微信&QQ群:
QQ群:533341697
微信群:添加GreatSQL社区助手(微信号:wanlidbc
)好友,待社区助手拉您进群。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
长上下文LLMs:RAG 的终结者还是最佳搭档?
编者按:随着大语言模型(LLMs)的上下文窗口不断扩大,您是否开始思考:我们还需要花费大量时间和资源来构建复杂的检索增强生成(RAG)系统吗? 本文深入探讨了长上下文 LLMs 与 RAG 系统的优劣势,揭示了它们在实际应用中的表现差异。通过对最新四篇学术研究的全面分析,作者阐明了长上下文 LLMs 在某些任务中的优势,同时也指出了 RAG 系统在某些专业领域任务和成本效益方面仍具有优势。 作者建议将 RAG 与长上下文 LLMs 结合使用,以发挥协同效应,并呼吁建立更全面、更严格的评估体系,包括统一的评估数据集和评估指标。未来,如何有效结合这两种技术,应当是人工智能领域的一个重要研究方向。 作者 | Florian June 编译 | 岳扬 2023 年,大语言模型(LLMs)的上下文窗口通常在 4K 到 8K 左右。但到了 2024 年 7 月,上下文窗口超过 128K 的 LLMs 已经变得很普遍了。 以 Claude 2[1] 为例,其上下文窗口可达 100K。Gemini 1.5[2] 则宣称能够处理 2M 的上下文信息,而 LongRoPE[3] 更是将 LLMs 的上下文...
- 下一篇
深度解析云原生混部解决方案
摘要:Volcano推出的云原生混部解决方案,从应用层到内核提供端到端的资源隔离与共享机制,最大化提升资源利用率。 本文来源:《华为云DTSE》第五期开源专刊,作者:王雷博 华为云架构师、常旭征 华为云高级工程师 随着云原生技术的快速发展,越来越多的业务已逐渐迁移到Kubernetes,使用云原生化的方式进行开发维护,极大地简化了应用程序的部署、编排和运维,Kubernetes已逐渐成为云原生时代的“操作系统”。但在另一方面,应用云原生技术之后,数据中心的资源使用率仍然较低,为了提升资源利用率同时保障高优先级业务的SLO,Volcano推出了云原生混部解决方案,从应用层到内核提供端到端的资源隔离与共享机制,最大化提升资源利用率。 背景 何为云原生混部 企业部署的业务类型从其运行特点来看,大致可以分为两类:在线业务和离线业务,分别有如下的特征。 云原生混部是指通过云原生的方式将在线业务和离线业务部署在同一个集群。由于在线业务运行具有明显的波峰波谷特征,因此当在线业务运行在波谷时,离线业务可以利用这部分空闲的资源,当在线业务到达波峰时,通过在线作业优先级控制等手段压制离线作业的运行,保障在...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- MySQL8.0.19开启GTID主从同步CentOS8
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- Red5直播服务器,属于Java语言的直播服务器
- CentOS7,8上快速安装Gitea,搭建Git服务器
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- SpringBoot2全家桶,快速入门学习开发网站教程
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库