首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答
筛选
回答情况:
全部无回答回答未采纳
提问时间:
不限一周内一月内三月内一年内
回答标签:
mysql

MySQL 8.0统计信息不准确?

提问2021-01-271.3K
刺激
回答来自于问答智囊团成员:王文安@DBA 专栏:https://cloud.tencent.com/developer/user/7566357 原因剖析 实际上是MySQL 8.0为了提高information_schema的查询效率,将表和统计信息放入内部的统计信息缓存起来,缓存时间由参数information_schema_stats_expiry决定,至少为86400s;如果想获取最新的统计信息,可以通过如下两种方式: (1)分析表进行表分析 (2)设置information_schema_stats_expiry = 0 继续探索 那么统计信息不准确,会带来哪些影响呢?或者会影响执行计划呢?然后我们再次进行测试 测试1:表test记录数100,表sbtest1记录数100w 执行如下SQL,查看执行计划,走的是NLJ,小表test作为驱动表(全表扫描),大表sbtest1作为被驱动表(主键关联),执行效率很快 mysql >从测试中选择count (* ) ;+ - - - - - + | 数(* )| + - - - - - + | 100 | + - - - - - + 1行中集合(0.00秒) mysql >从sbtest1选择计数(* ) ; + - - - - - + | 数(* )| + - - - - - + | 1000000 | + - - - - - + 1行中集合(0.02秒) mysql >从table_name = 'test'的表中选择table_schema , table_name , table_rows ; + - - - - - - - + - - - - - - + - - - - - - + | TABLE_SCHEMA | TABLE_NAME | TABLE_ROWS | + - - - - - - - + - - - - - - + - - - - - - + | 测试 | 测试 | 100 | + - - - - - - - + - - - - - - + - - - - - - + 1行中 集合 (0.00秒) mysql >从table_name = 'sbtest1'的表中选择table_schema , table_name , table_rows ; + - - - - - - - + - - - - - - + - - - - - - + | TABLE_SCHEMA | TABLE_NAME | TABLE_ROWS | + - - - - - - - + - - - - - - + - - - - - - + | 测试 | sbtest1 | 947468 | + - - - - - - - + - - - - - - + - - - - - - + 1行中 集合 (0.01秒) mysql >选择t 。* 来自于t的测试t内部联接sbtest1 t1 。id = t1 。id在哪里t 。c = '08566691963-88624912351-16662227201-46648573979-64646226163-77505759394-75470094713-41097360717-15161106334-50535565977'和t1 。c = '08566691963-88624912351-16662227201-46648573979-64646226163-77505759394-75470094713-41097360717-15161106334-50535565977' ; + - - + - - - - + - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + | id | k | c | 垫 | + - - + -- - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + | 1 | 501885 | 08566691963 - 88624912351 - 16662227201 - 46648573979 -64646226163 - 77505759394 - 75470094713 - 41097360717 - 15161106334 - 50535565977 | 63188288836 - 92351140030 - 06390587585 - 66802097351 - 49282961843 | + - - + - - - - + - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - + 1行中 集合 (0.00秒) mysql >说明选择t 。* 来自于t的测试t内部联接sbtest1 t1 。id = t1 。id在哪里t 。c = '08566691963-88624912351-16662227201-46648573979-64646226163-77505759394-75470094713-41097360717-15161106334-50535565977'和t1 。Ç = ' 08566691963 - 88624912351 - 16662227201 - 4664 + - - + - - - - - - - + - - -- + - - - - - - + - - - - + - - - - - - - - + - - - - - + - - - - - + - - - - - - + - - - + - - - - - + - - - - - -- + | id | select_type | 桌子| 隔板| 键入 | 可能的钥匙| 关键 | key_len | 参考 | 行| 过滤| 额外 | + - - + - - - - - - - + - - - - + - - - - - - + -- - - + - - - - - - - - + - - - - - + - - - - - + - - - - - - - + - - - + - - - - - + - - - - - - - + | 1 | SIMPLE | t |NULL | 全部 | 主要 | NULL | NULL | NULL | 100 | 10.00 | 使用Where | | 1 | SIMPLE | t1 | NULL | eq_ref | 主要 | 主要| 4 | 测试。Ť 。id | 1 | 10.00 | 使用Where | + - -+ - - - - - - - + - - - - + - - - - - - + - - - - + - - - - - - - - - + - - - - - + - - - - - + - - - - - - + - - - +- - - - - + - - - - - - - + 2行中 集合, 1个 警告 (0.00秒) 测试2:表test记录数1000w左右,表sbtest1记录数100w 再次执行SQL,查看执行计划,走的也是NLJ,相对小表sbtest1作为驱动表,大表测试作为被驱动表,也是正确的执行计划 mysql >从测试中选择count (* ) ;+ - - - - - + | 数(* )| + - - - - - + | 10000100 | + - - - - - + 1行中集合(0.33秒) mysql >从sbtest1选择计数(* ) ; + - - - - - + | 数(* )| + - - - - - + | 1000000 | + - - - - - + 1行中集合(0.02秒) mysql >从table_name = 'test'的表中选择table_schema , table_name , table_rows ; + - - - - - - - + - - - - - - + - - - - - - + | TABLE_SCHEMA | TABLE_NAME | TABLE_ROWS | + - - - - - - - + - - - - - - + - - - - - - + | 测试 | 测试 | 100 | + - - - - - - - + - - - - - - + - - - - - - + 1行中 集合 (0.00秒) mysql >从table_name = 'sbtest1'的表中选择table_schema , table_name , table_rows ; + - - - - - - - + - - - - - - + - - - - - - + | TABLE_SCHEMA | TABLE_NAME | TABLE_ROWS | + - - - - - - - + - - - - - - + - - - - - - + | 测试 | sbtest1 | 947468 | + - - - - - - - + - - - - - - + - - - - - - + 1行中 集合 (0.01秒) mysql >选择t 。* 来自于t的测试t内部联接sbtest1 t1 。id = t1 。id在哪里t 。c = '08566691963-88624912351-16662227201-46648573979-64646226163-77505759394-75470094713-41097360717-15161106334-50535565977'和t1 。c = '08566691963-88624912351-16662227201-46648573979-64646226163-77505759394-75470094713-41097360717-15161106334-50535565977' ; + - - + - - - - + - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + | id | k | c | 垫 | + - - + -- - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + | 1 | 501885 | 08566691963 - 88624912351 - 16662227201 - 46648573979 -64646226163 - 77505759394 - 75470094713 - 41097360717 - 15161106334 - 50535565977 | 63188288836 - 92351140030 - 06390587585 - 66802097351 - 49282961843 | + - - + - - - - + - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - + 1行中 集合 (0.37秒) mysql >说明选择t 。* 来自于t的测试t内部联接sbtest1 t1 。id = t1 。id在哪里t 。c = '08566691963-88624912351-16662227201-46648573979-64646226163-77505759394-75470094713-41097360717-15161106334-50535565977'和t1 。c = '08566691963-88624912351-16662227201-46648573979-64646226163-77505759394-75470094713-41097360717-15161106334-50535565977' ; + - - + - - - - - - - + - - -- + - - - - - - + - - - - + - - - - - - - - + - - - - - + - - - - - + - - - - - - + - - - - + - - - - - + - - - - - -- - + | id | select_type | 桌子| 隔板| 键入 | 可能的钥匙| 关键 | key_len | 参考 | 行 | 过滤| 额外 | + - - + - - - - - - - + - - - - + - - - - - - +- - - - + - - - - - - - - + - - - - - + - - - - - + - - - - - - - + - - - - + - - - - - + - - - - - - - + | 1 | SIMPLE |t1 | NULL | 全部 | 主要 | NULL | NULL | NULL | 947468 | 10.00 | 使用Where | | 1 | SIMPLE | t | NULL | eq_ref | 主要 | 主要| 4 | 测试。T1 。id | 1 | 10.00 | 使用Where | + - - + - - - - - - - + - - - - + - - - - - - + - - - - + - - - - - - - - + - - - - - + - - - - - + - - - - - - + - --- - - + - - - - - + - - - - - - - + 2行中集合,1个警告(0.01秒) 为什么优化器没有选择错误的执行计划呢?之前文章也提过,MySQL 8.0是将元数据信息存放在MySQL库下的数据字典表里,information_schema库只是提供相对方便的视图供用户查询,所以优化器在选择执行计划时,会从数据字典表中获取统计信息,生成正确的执行计划。 总结 MySQL 8.0为了提高information_schema的查询效率,将视图和表的内部信息统计缓存起来,缓存时间由参数information_schema_stats_expiry决定(建议设置该参数为0);这可能会导致用户查询上方视图时,无法获取最新,准确的统计信息,但并不会影响执行计划的选择。
5人回答了此问题

CPU 100%,MySQL 到底在干什么?

lllspeed
回答来自于问答智囊团成员:王文安@DBA 专栏:https://cloud.tencent.com/developer/user/7566357 怎么看懂 CPU 使用率 以 Linux 的 top 命令为例,效果如下: 📷 Top 命令 在 %CPU 这一列就展示了 CPU 的使用情况,百分比指代的是总体上占用的时间百分比: %us:表示用户进程的 CPU 使用时间(没有通过 nice 调度) %sy:表示系统进程的 CPU 使用时间,主要是内核使用。 %ni:表示用户进程中,通过 CPU 调度(nice)过的使用时间。 %id:空闲的 CPU 时间 %wa:CPU 运行时在等待 IO 的时间 %hi:CPU 处理硬中断花费的时间 %si:CPU 处理软中断花费的时间 %st:被虚拟机偷走的 CPU 时间 通常情况下,我们讨论的 CPU 使用率过高,指的是 %us 这个指标,监控里面的 CPU 使用率通常也是这个值(也有用其他的方法计算出来的,不过简单起见,不考虑其他的情况 )。其他几个指标过高也代表出 MySQL 的状态异常,简单起见,这里主要还是指 %us 过高的场景。 MySQL 和线程 MySQL 是单进程多线程的结构,意味着独占的 MySQL 服务器里面,只能用 top 命令看到一行数据。 📷 TOP 命令效果 这里能看到的是 MySQL 的进程 ID,如果要看到线程的情况,需要用top -H 📷 TOP 命令效果 在这里能看到的是 MySQL 各个线程的 ID,可以看到 MySQL 在启动之后,会创建非常多的内部线程来工作。 这些内部线程包括 MySQL 自己用来刷脏,读写数据等操作的系统线程,也包括处理用户 SQL 的线程,姑且叫做用户线程吧。用户线程有一个特殊的地方:程序端发送到 MySQL 端的 SQL,只会由一个用户线程来执行(one-thread-per-connection),所以 MySQL 在处理复杂查询的时候,会出现“一核有难,多核围观”的尴尬现象。 参考 %us 的定义,对于 Linux 系统来说,MySQL 进程和它启动的所有线程都不算内核进程,因此 MySQL 的系统线程和用户线程在繁忙的时候,都会体现在 CPU 使用率的 %us 指标上。 MySQL 干什么的时候,CPU 会 100% 从前文的分析来看,MySQL 主要是两类线程占用 CPU:系统线程和用户线程。因此 MySQL 独占的服务器上,只需要留意一下这两类线程的情况,就能 Cover 住绝大部分的问题场景。 系统线程 在实际的环境中,系统线程遇到问题的情况会比较少,一般来说,多个系统线程很少会同时跑满,只要服务器的可用核心数大于等于 4 的话,一般也不会遇到 CPU 100%,当然有一些 bug 可能会有影响,比如这个: 📷 MySQL BUG 虽然情况比较少,但是在面对问题的常规排查过程中,系统线程的问题也是需要关注的。 用户线程 提到用户线程繁忙,很多时候肯定会第一时间凭经验想到慢查询。确实 90% 以上的时候都是“慢查询”引起的,不过作为方法论,还是要根据分析再去得出结论的~ 参考 us% 的定义,是指用户线程占用 CPU 的时间多少,这代表着用户线程占用了大量的时间。 一方面是在进行长时间的计算,例如:order by,group by,临时表,join 等。这一类问题可能是查询效率不高,导致单个 SQL 语句长时间占用 CPU 时间,也有可能是单纯的数据量比较多,导致计算量巨大。另一方面是单纯的 QPS 压力高,所以 CPU 的时间被用满了,比如 4 核的服务器用来支撑 20k 到 30k 的点查询,每个 SQL 占用的 CPU 时间并不多,但是因为整体的 QPS 很高,所以 CPU 的时间被占满了。 怎么定位问题? 分析完之后,就要开始实战了,这里根据前文的分析给出一些经典的 CPU 100% 场景,并给出简要的定位方法作为参考。 PS:系统线程的 bug 的场景 skip,以后有机会再作为详细的案例来分析。 慢查询 在 CPU 100% 这个问题已经发生之后,真实的慢查询和因为 CPU 100% 导致被影响的普通查询会混在一起,难以直观的看 processlist 或者 slowlog 来发现元凶,这时候就需要一些比较明确的特征来进行甄别。 从前文的简单分析可以看出来,查询效率不高的慢查询通常有以下几种情况: 全表扫描:Handler_read_rnd_next 这个值会大幅度突增,且这一类查询在 slowlog 中 row_examined 的值也会非常高。 索引效率不高,索引选错了:Handler_read_next 这个值会大幅度的突增,不过要注意这种情况也有可能是业务量突增引起的,需要结合 QPS/TPS 一起看。这一类查询在 slowlog 中找起来会比较麻烦,row_examined 的值一般在故障前后会有比较明显的不同,或者是不合理的偏高。 比如数据倾斜的场景,一个小范围的 range 查询在某个特定的范围内 row_examined 非常高,而其他的范围时 row_examined 比较低,那么就可能是这个索引效率不高。 排序比较多:order by,group by 这一类查询通常不太好从 Handler 的指标直接判断,如果没有索引或者索引不好,导致排序操作没有消除的话,那么在 processlist 和 slowlog 通常能看到这一类查询语句出现的比较多。 当然,不想详细的分析 MySQL 指标或者是情况比较紧急的话,可以直接在 slowlog 里面用 rows_sent 和 row_examined 做个简单的除法,比如 row_examined/rows_sent > 1000 的都可以拿出来作为“嫌疑人”处理。这类问题一般在索引方面做好优化就能解决。 PS:1000 只是个经验值,具体要根据实际业务情况来定。 计算量大 这一类问题通常是因为数据量比较大,即使索引没什么问题,执行计划也 OK,也会导致 CPU 100%,而且结合 MySQL one-thread-per-connection 的特性,并不需要太多的并发就能把 CPU 使用率跑满。这一类查询其实是是比较好查的,因为执行时间一般会比较久,在 processlist 里面就会非常显眼,反而是 slowlog 里面可能找不到,因为没有执行完的语句是不会记录的。 这一类问题一般来说有三种比较常规的解决方案: 读写分离,把这一类查询放到平时业务不怎么用的只读从库去。 在程序段拆分 SQL,把单个大查询拆分成多个小查询。 使用 HBASE,Spark 等 OLAP 的方案来支持。 高 QPS 这一类问题单纯的就是硬件资源的瓶颈,不论是 row_examined/rows_sent 的比值,还是 SQL 的索引、执行计划,或者是 SQL 的计算量都不会有什么明显问题,只是 QPS 指标会比较高,而且 processlist 里面可能什么内容都看不到,例如: 📷 processlist 总结一下 实际上 CPU 100% 的问题其实不仅仅是单纯的 %us,还会有 %io,%sys 等,这些会涉及到 MySQL 与 Linux 相关联的一部分内容,展开来就会比较多了。本文仅从 %us 出发尝试梳理一下排查&定位的思路和方法,在分析 %io,%sys 等方面的问题时,也可以用类似的思路,从这些指标的意义开始,结合 MySQL 的一些特性或者特点,逐步理清楚表象背后的原因。
1人回答了此问题

关于登录时到底是被 MySQL 识别为哪个账号的问题?

晓小峰哦
简要分析 MySQL 在创建用户的时候,一般是需要指定用户名和来源 IP 的,比如: mysql> show grants for test@'%'; +----------------------------------+ | Grants for test@% | +----------------------------------+ | GRANT USAGE ON *.* TO 'test'@'%' | +----------------------------------+ 1 row in set (0.00 sec) 由于 Host 这个字段支持正则匹配,因此这个字段设置为 % 的时候,则代表所有的来源 IP 都能匹配到。 因为这个特性,所以有时候创建的账号会有如下的情况出现: +------+---------------+ | user | host | +------+---------------+ | test | % | | test | 10.104.% | | test | 10.104.56.136 | +------+---------------+ 参考官方文档的描述: When multiple matches are possible, the server must determine which of them to use. It resolves this issue as follows: 1.Whenever the server reads the user table into memory, it sorts the rows. 2.When a client attempts to connect, the server looks through the rows in sorted order. 3.The server uses the first row that matches the client host name and user name. The server uses sorting rules that order rows with the most-specific Host values first. 简而言之:MySQL 会按照 Host 的匹配精度,按降序排列同一个 Username 的所有账号,当 Client 端尝试登录 MySQL 的时候,会按照顺序依次这个 Username 下面所有的 Host 规则,直到匹配成功。 Host 这个字段不仅能填 IP,也能写域名,同样也能利用到正则表达式匹配: 📷 匹配示例 由于域名指向的 IP 受 DNS 的影响,因此多数时候会用 IP,一般来说需要 DNS 来屏蔽一些后端细节的时候才会用域名来作为 Host 字段的值。 测试一下 使用如下操作创建三个用户,密码不做区分: mysql> create user test@'%' identified by 'test'; Query OK, 0 rows affected (0.00 sec) mysql> create user test@'10.104.56.136' identified by 'test'; Query OK, 0 rows affected (0.00 sec) mysql> create user test@'10.104.%' identified by 'test'; Query OK, 0 rows affected (0.01 sec) mysql> mysql> mysql> mysql> select user,host from mysql.user where user='test' order by host desc; +------+---------------+ | user | host | +------+---------------+ | test | 10.104.56.136 | | test | 10.104.% | | test | % | +------+---------------+ 3 rows in set (0.00 sec) mysql> PS:order by desc 仅为展示上的考虑。 那么从两个不同的机器上(10.104.56.136 和 10.104.43.107)尝试登录 MySQL,按照文档的描述,匹配的优先级应该是:10.104.56.136->10.104.%->%。那么有一台服务器能完整匹配到 IP,另外一台服务器匹配到的应该是10.104.%。 实际操作一下看看效果: root@debian:~# ifconfig eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 10.104.56.136 ......(省略) root@debian:~# mysql -h192.168.1.100 -utest -ptest ......(省略) Server version: 5.7.18-txsql-log 20200331 ......(省略) mysql> show grants; +----------------------------------------------+ | Grants for test@10.104.56.136 | +----------------------------------------------+ | GRANT USAGE ON *.* TO 'test'@'10.104.56.136' | +----------------------------------------------+ 1 row in set (0.00 sec) mysql> 在另外一台机器上: root@VM-43-107-debian:~# ifconfig eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 10.104.43.107 ......(省略) root@debian:~# mysql -h192.168.1.100 -utest -ptest ......(省略) Server version: 5.7.18-txsql-log 20200331 ......(省略) mysql> show grants; +-----------------------------------------+ | Grants for test@10.104.% | +-----------------------------------------+ | GRANT USAGE ON *.* TO 'test'@'10.104.%' | +-----------------------------------------+ 1 row in set (0.00 sec) mysql> 换成本地的设备再试一下登录: Tomo@MacBook-Pro ~ % mysql -hgz-cdb.sql.tencentcdb.com -utest -ptest -P59888 ......(省略) Server version: 5.7.18-txsql-log 20200331 ......(省略) mysql> show grants; +----------------------------------+ | Grants for test@% | +----------------------------------+ | GRANT USAGE ON *.* TO 'test'@'%' | +----------------------------------+ 1 row in set (0.02 sec) mysql> 可以看到本地设备的 IP 由于和前两个匹配规则不一致,所以最后匹配到了 % 的这个账号。 总结一下 作为比较保险的办法,尽量少用 Host 来区分不同的账号,直接用不同的 Username 会比较好管理和维护,如果一定需要用 Host 来区分,那么至少也要用不同的密码,防止匹配到了错误的用户,导致权限不足引起业务上的问题。 课外题 localhost 和 127.0.0.1 算是常用的两个 Host,可以作为实践内容动手试一下,体验一下匹配的规律。在 MySQL 看来,精确的域名和精确的 IP 是同等地位的。
1人回答了此问题

如何配置MySQL存储过程?

提问2018-11-091.9K
秋千
执行存储过程 MySQL称存储过程的执行为调用,因此MySQL执行存储过程的语句为CALL    .CALL接受存储过程的名字以及需要传递给它的任意参数 CALL productpricing(@pricelow , @pricehigh , @priceaverage); //执行名为productpricing的存储过程,它计算并返回产品的最低、最高和平均价格  创建存储过程 CREATE  PROCEDURE 存储过程名()  一个例子说明:一个返回产品平均价格的存储过程如下代码: CREATE  PROCEDURE productpricing() BEGIN SELECT Avg(prod_price)  AS priceaverage FROM products; END; //创建存储过程名为productpricing,如果存储过程需要接受参数,可以在()中列举出来。即使没有参数后面仍然要跟()。BEGIN和END语句用来限定存储过程体,过程体本身是个简单的SELECT语句  在MYSQL处理这段代码时会创建一个新的存储过程productpricing。没有返回数据。因为这段代码时创建而不是使用存储过程。 Mysql命令行客户机的分隔符  默认的MySQL语句分隔符为分号 ; 。Mysql命令行实用程序也是 ; 作为语句分隔符。如果命令行实用程序要解释存储过程自身的 ; 字符,则他们最终不会成为存储过程的成分,这会使存储过程中的SQL出现句法错误  解决方法是临时更改命令实用程序的语句分隔符 DELIMITER //  //定义新的语句分隔符为// CREATE PROCEDURE productpricing() BEGIN SELECT Avg(prod_price) AS priceaverage FROM products; END // DELIMITER ;  //改回原来的语句分隔符为 ;  除\符号外,任何字符都可以作为语句分隔符 CALL productpricing();  //使用productpricing存储过程  执行刚创建的存储过程并显示返回的结果。因为存储过程实际上是一种函数,所以存储过程名后面要有()符号  删除存储过程 DROP PROCEDURE productpricing ;  //删除存储过程后面不需要跟(),只给出存储过程名  为了删除存储过程不存在时删除产生错误,可以判断仅存储过程存在时删除 DROP PROCEDURE IF EXISTS  使用参数 Productpricing只是一个简单的存储过程,他简单地显示SELECT语句的结果。  一般存储过程并不显示结果,而是把结果返回给你指定的变量 CREATE PROCEDURE productpricing( OUT p1 DECIMAL(8,2), OUT ph DECIMAL(8,2), OUT pa DECIMAL(8,2), ) BEGIN SELECT Min(prod_price) INTO p1 FROM products; SELECT Max(prod_price) INTO ph FROM products; SELECT Avg(prod_price) INTO pa FROM products; END;  此存储过程接受3个参数,p1存储产品最低价格,ph存储产品最高价格,pa存储产品平均价格。每个参数必须指定类型,这里使用十进制值。关键字OUT指出相应的参数用来从存储过程传给一个值(返回给调用者)。MySQL支持IN(传递给存储过程)、OUT(从存储过程中传出、如这里所用)和INOUT(对存储过程传入和传出)类型的参数。存储过程的代码位于BEGIN和END语句内,如前所见,它们是一些列SELECT语句,用来检索值,然后保存到相应的变量(通过INTO关键字)  调用修改过的存储过程必须指定3个变量名: CALL productpricing(@pricelow , @pricehigh , @priceaverage);  这条CALL语句给出3个参数,它们是存储过程将保存结果的3个变量的名字  变量名  所有的MySQL变量都必须以@开始  使用变量 SELECT @priceaverage ; SELECT @pricelow , @pricehigh , @priceaverage ;   //获得3给变量的值  下面是另一个例子,这次使用IN和OUT参数。ordertotal接受订单号,并返回该订单的合计 CREATE PROCEDURE ordertotal( IN onumber INT, OUT ototal DECIMAL(8,2) ) BEGIN SELECT Sum(item_price*quantity) FROM orderitems WHERE order_num = onumber INTO ototal; END; //onumber定义为IN,因为订单号时被传入存储过程,ototal定义为OUT,因为要从存储过程中返回合计,SELECT语句使用这两个参数,WHERE子句使用onumber选择正确的行,INTO使用ototal存储计算出来的合计  为了调用这个新的过程,可以使用下列语句: CALL ordertotal(2005 , @total);  //这样查询其他的订单总计可直接改变订单号即可 SELECT @total; 建立智能的存储过程  上面的存储过程基本都是封装MySQL简单的SELECT语句,但存储过程的威力在它包含业务逻辑和智能处理时才显示出来  例如:你需要和以前一样的订单合计,但需要对合计增加营业税,不活只针对某些顾客(或许是你所在区的顾客)。那么需要做下面的事情: 1 获得合计(与以前一样) 2 吧营业税有条件地添加到合计 3 返回合计(带或不带税)  存储过程的完整工作如下: — Name: ordertotal — Parameters: onumber = 订单号 —   taxable = 1为有营业税 0 为没有 —   ototal = 合计 CREATE  PROCEDURE ordertotal( IN onumber INT, IN taxable BOOLEAN, OUT ototal DECIMAL(8,2) — COMMENT()中的内容将在SHOW PROCEDURE STATUS ordertotal()中显示,其备注作用 ) COMMENT ‘Obtain order total , optionally adding tax’ BEGIN — 定义total局部变量 DECLARE total DECIMAL(8,2) DECLARE taxrate INT DEFAULT 6; — 获得订单的合计,并将结果存储到局部变量total中 SELECT Sum(item_price*quantity) FROM orderitems WHERE order_num = onumber INTO total; — 判断是否需要增加营业税,如为真,这增加6%的营业税 IF taxable THEN SELECT total+(total/100*taxrate) INTO total;  END IF; — 把局部变量total中才合计传给ototal中 SELECT total INTO ototal; END;  此存储过程有很大的变动,首先,增加了注释(前面放置—)。在存储过程复杂性增加时,这样很重要。在存储体中,用DECLARE语句定义了两个局部变量。DECLARE要求制定变量名和数据类型,它也支持可选的默认值(这个例子中taxrate的默认设置为6%),SELECT 语句已经改变,因此其结果存储到total局部变量中而不是ototal。IF语句检查taxable是否为真,如果为真,则用另一SELECT语句增加营业税到局部变量total,最后用另一SELECT语句将total(增加了或没有增加的)保存到ototal中。  COMMENT关键字  本列中的存储过程在CREATE PROCEDURE 语句中包含了一个COMMENT值,他不是必需的,但如果给出,将在SHOW PROCEDURE STATUS的结果中显示 IF语句  这个例子中给出了MySQL的IF语句的基本用法。IF语句还支持ELSEIF和ELSE子句(前者还使用THEN子句,后者不使用)  检查存储过程  为显示用来创建一个存储过程的CREATE语句,使用SHOW CREATE PROCEDURE语句 SHOW CREATE PROCEDURE ordertotal;  为了获得包括何时、有谁创建等详细信息的存储过程列表。使用SHOW PROCEDURE STATUS.限制过程状态结果,为了限制其输出,可以使用LIKE指定一个过滤模式,例如:SHOW PROCEDURE STATUS LIKE ”ordertotal;
5人回答了此问题

大佬们,妹妹有个问题希望大佬们求助?

西里国际站
我认为,redis,数据库分出来,然后再组,这样可以解决数据溜滞问题,我采用了,每个功能一个服务器配置,这样可以解决,哪里问题,一目了然!我境站商城,采用了15个模块化服务器,然后通过网的形式组成服务器!快!
4人回答了此问题

相同的SQL查询,在腾讯云mysql数据库和普通mysql里返回的结果顺序不一致是什么原因呢?

编辑2025-01-1464
云海泛舟客
我感觉问题不是很大吧……可能跟数据库底层设计有关,也可能跟数据插入时候,底层存储空间位置有关。 anyway,展现的时候,前端自己加个排序应该也是常规操作吧……
2人回答了此问题

如果发现当前的业务已经超出原技术能力支撑的时候,应该寻求哪些方法呢?

架构师之路
分享三个点: 1. 一切方案设计,架构设计都是折衷:老版本能用,但低效;新版本高效,但重构代价大。技术人经常会遇到类似的问题。 2. 多思考当下的主要矛盾:当下,研发效率维护效率代价大(考虑中长期),还是重构升级代价大(一次性成本)。 3. 多站在老板的角度思考问题:想一想,如果你是老板,他会怎么选。 多说一句,我们现在也还是5.7,8.0的新东西不必须,5.7够用。
6人回答了此问题

腾讯云mysql数据库设置自增id为什么不从1开始?

胖五斤
看起来这个id是你的插件mybatisplus自动生成的,如果用数据库默认的,会从1开始。
1人回答了此问题

tdsql 目前有社区版吗?

编辑2024-10-28330
用户10722042
我也找了好久,哪位大佬可以分享下。
1人回答了此问题

关于轻量云服务器内网连接mysql云数据库的问题?

快乐的小白
可以内网互通的。如果对文档实在是看不懂的话,可以发个工单,让腾讯云的技术跟你指导下。
1人回答了此问题

MYSQL Enter password不让输入密码?

编辑2024-08-15103
快乐的小白
是不是输入啥,都不显示? 其实就是不显示的.....你直接回车确认就行了
1人回答了此问题

云开发是否支持连接自有的 MySQL 数据库?

编辑2024-07-26151
腾讯云开发TCB
目前云开发暂不支持使用自有的 MySQL 数据库,但该功能已在开发计划中(预计8月上线内测)。
1人回答了此问题

云开发的 MySQL 功能已经上线了吗?

编辑2024-07-2666
腾讯云开发TCB
是的,MySQL 功能已经发布。您可以登录云后台(https://tcb.cloud.tencent.com/),在"数据模型"部分找到并使用 MySQL 数据库服务。
1人回答了此问题

为什么MybatisPlus更改变量名导致的查询错误?

编辑2024-05-10116
huazie
检查下你的 application.properties 配置,看看是不是有 mybatis-plus.configuration.map-underscore-to-camel-case=true
1人回答了此问题

mysql怎么解决子查询返回结果为空导致sql执行很慢?

编辑2024-04-09232
空洞的盒子
对表构造适当的索引,使用Join来替代子查询,然后使用exists语法来简化查询语句,可以适当对空结果集进行判断。
2人回答了此问题

GROUP BY返回多行提问?

编辑2024-01-27111
小明互联网技术分享社区
group by 属于分组,会出现多行,这个需要根据分组后的数据 join的方式进行连接,不能放在现在的子查询里面
1人回答了此问题

seatunnel mysql 同步数据,怎么解决?

编辑2024-01-12814
一凡sir
数据类型不匹配的错误 Caused by: java.lang.ClassCastException: cannot assign instance of io.debezium.relational.TableId to field org.apache.seatunnel.connectors.cdc.base.source.split.SnapshotSplit.tableId of type io.debezium.relational.TableId in instance of org.apache.seatunnel.connectors.cdc.base.source.split.SnapshotSplit
1人回答了此问题

在云服务器中创建了数据库,第二天,该数据库没有了?

一凡sir
创建工单问问客服吧,真的出现这种情况,可就是事故了。 自己还是要做好每天的数据库备份才行。
1人回答了此问题

TDSQL-C MySQL 版 如何优化参数配置,提高性能?

一凡sir
根据性能需求进行调整:根据性能评估的结果和需求,调整参数配置。以下是一些常见的参数配置调整建议: innodb_buffer_pool_size:该参数确定了InnoDB引擎使用的内存缓冲区大小,可以根据数据库服务器的可用内存来增加或减少该值。较大的缓冲池可以提高读写性能。 innodb_log_file_size:该参数确定了InnoDB引擎的日志文件的大小,可以根据应用的写入负载和性能需求进行调整。 query_cache_size:该参数决定了查询缓存的大小,可以根据查询的频率和性能需求进行调整。在高并发环境下,该值可能需要设置为0来避免争夺缓存造成的性能下降。 key_buffer_size:该参数决定了MyISAM引擎使用的键缓冲区大小,对于使用MyISAM表的应用可以适当增大该值,以提高读取性能。 进一步调优:除了基本的参数配置,还可以考虑以下优化措施: 合理设计表结构和索引,以提高查询性能。 使用Explain语句来分析查询语句的执行计划,并根据需要进行索引调整和查询优化。 监控MySQL的性能指标,如查询响应时间、连接数、缓冲区使用情况等,及时进行调整和优化。
1人回答了此问题
Hi~
今天想聊点什么呢?
近期活跃用户
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档