首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往
社区首页 >问答
筛选
回答情况:
全部无回答回答未采纳
提问时间:
不限一周内一月内三月内一年内
回答标签:
mysql

MySQL 8.0统计信息不准确?

提问2021-01-271.1K
刺激
回答来自于问答智囊团成员:王文安@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);这可能会导致用户查询上方视图时,无法获取最新,准确的统计信息,但并不会影响执行计划的选择。

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 的一些特性或者特点,逐步理清楚表象背后的原因。

关于登录时到底是被 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 是同等地位的。

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

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

如何配置MySQL存储过程?

提问2018-11-091.8K
秋千
执行存储过程 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;

GROUP BY返回多行提问?

编辑2024-01-2725
IT技术分享社区
group by 属于分组,会出现多行,这个需要根据分组后的数据 join的方式进行连接,不能放在现在的子查询里面

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

编辑2024-01-12332
一凡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

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

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

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的性能指标,如查询响应时间、连接数、缓冲区使用情况等,及时进行调整和优化。

关于数据库经常断开连接,缓存池问题等,请问有大神可以指教吗?

编辑2023-10-18171
一凡sir
程序长时间没有使用到数据库连接,它会自动断开链接,这是正常的。 在使用中遇到这类报错,重新创建连接就可以了。

mysql5.7如何授权才能实现只允许该用户查看自己的数据库,其它的数据库不允许查看?

编辑2023-09-26100
一凡sir
授予"new_user"用户在"mydb"数据库上的所有权限: GRANT ALL PRIVILEGES ON mydb.* TO 'new_user'@'localhost'; FLUSH PRIVILEGES; 没有给new_user用户设置其他数据库的权限,它就无法操作其他的数据了。

我的网站数据库部分发生异常,连接不上,请教大侠如何解决?

一凡sir
网络原因,使用ping/telnet命令,先确认mysql服务的ip和端口是否可以正常连接。

Ubuntu轻量应用服务器怎么安装mysql?

编辑2023-08-2989
一凡sir
在Ubuntu服务器上安装MySQL可以按照以下步骤进行: 步骤1:更新包列表 在开始安装之前,首先需要更新系统的包列表。打开终端窗口并运行以下命令: sudo apt update 步骤2:安装MySQL 运行以下命令来安装MySQL服务器: sudo apt install mysql-server 安装过程中,系统会提示你设置MySQL的root账户密码。 步骤3:配置MySQL 安装完成后,运行以下命令来配置MySQL服务器: sudo mysql_secure_installation 该命令将引导你进行一系列的安全设置,包括删除默认的匿名用户、禁止远程root登录等。根据自己的需求选择相应的选项即可。 步骤4:验证安装 安装完成后,可以通过以下命令来验证MySQL是否成功安装: sudo systemctl status mysql 如果MySQL正在运行,则表示安装成功。 以上就是在Ubuntu服务器上安装MySQL的步骤。

使用TDSQL有没有哪里和mysql不兼容???

编辑2023-10-16200
一凡sir
在使用TDSQL时,可能会遇到以下与MySQL不兼容的方面: 1. 存储引擎:TDSQL 默认使用 TiDB 引擎,而不是 MySQL 的 InnoDB 或 MyISAM。这可能会导致在 TDSQL 中无法使用特定存储引擎的功能或语法。 2. 事务隔离级别:TDSQL 默认使用 Serializable 隔离级别(与 MySQL 的默认隔离级别 Repeatable Read 不同),这可能会导致一些并发性问题和性能上的差异。 3. 非确定性函数:某些 MySQL 的非确定性函数在 TDSQL 中可能会有不同的行为,这可能导致查询结果不同。 4. 存储过程和触发器:TDSQL 的存储过程和触发器功能与 MySQL 的功能不完全一致,可能需要进行一些调整和迁移。 5. 特定语法和语义:TDSQL 与 MySQL 在某些语法和语义上可能存在差异,可能需要进行一些更改和调整。 需要注意的是,TDSQL 是一个兼容 MySQL 协议的分布式数据库,它确保了与 MySQL 兼容性的一致性,但并不意味着所有的功能和语法都完全相同。在迁移或使用 TDSQL 时,建议进行充分的测试和验证,以确保所需的功能和行为都符合预期。

使用MySql通过二级索引+回表的方式执行查询时,为什么索引列中重复值过多会导致大量回表操作?

编辑2023-04-19323
程序那些事儿
当使用二级索引+回表的方式进行查询时,如果索引列中的重复值过多,就会导致大量的回表操作。 这是因为MySQL的二级索引结构是B+树,B+树的叶子节点存储了数据行的主键值和其它字段的值,而非主键值的索引列只是作为B+树的一部分,用于定位到叶子节点。因此,当查询条件中包含非主键值的索引列时,MySQL需要先通过B+树定位到叶子节点,再根据叶子节点中的主键值回表查询数据行。 如果索引列中重复值过多,那么同一个叶子节点中可能会包含大量的数据行,这就意味着需要进行大量的回表操作才能获取所有符合查询条件的数据行。这将导致查询性能变得非常低下,甚至会出现性能瓶颈。 因此,为了避免这种情况,我们可以在创建索引时尽量避免选择重复值过多的列作为索引列,或者使用联合索引来减少重复值过多的情况。

2023mysql流行版本是?

编辑2023-02-16551
IT技术分享社区
推荐安装mysql8.0 目前主流的 MySQL 版本包括 MySQL 8.0、MySQL 5.7、MySQL 5.6、MySQL 5.5 等。其中 MySQL 8.0 是最新版本,引入了许多新功能和性能优化,包括高级管理、 JSON 功能、地理空间数据类型和查询、SQL 生成器等。MySQL 5.7 和 MySQL 5.6 也都有许多值得注意的特性和改进,例如支持 NoSQL 引擎、性能和安全性优化等,每个版本都有其适用的场景和优势。

C#/C++如何操作腾讯云MySQL?

编辑2022-02-17137
EatRice
您好,可以下载相应语言的SDK进行操作哦。API Exlporer里面有详细的信息,包括SDK下载地址和示例代码:https://console.cloud.tencent.com/api/explorer?Product=cvm&Version=2017-03-12&Action=DescribeZones&SignVersion= 打开如下图所示: image.png

2022-02-07:k8s安装mysql,yaml如何写?(非面试题)?

编辑2022-02-0787
卖女孩的火柴回答已采纳
apiVersion: v1 kind: ReplicationController metadata: name: mysql-rc labels: name: mysql-rc spec: replicas: 1 selector: name: mysql-pod template: metadata: labels: name: mysql-pod spec: containers: - name: mysql image: mysql imagePullPolicy: IfNotPresent ports: - containerPort: 3306 env: - name: MYSQL_ROOT_PASSWORD value: "mysql"

购买的云数据库MySQL 如何不区分大小写?

编辑2019-02-131.2K
不知雨
在 etc/my.cnf 文件中,  添加不区分大小写的设置。  lower_case_table_names=1      注意:0:区分大小写 ,1:不区分大小写
Hi~
今天想聊点什么呢?
近期活跃用户
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档