mysql高级变量查询(MySQL 使用自定义变量进行查询优化)
mysql高级变量查询
MySQL 使用自定义变量进行查询优化优化排序查询
自定义变量的一个重要特性是你可以同时将该变量的数学计算后的结果再赋值给该变量,类似于我们的 i = i + 1这种方式。下面是一个用于计算数据表行号的例子:
|
set @rownum := 0; select actor_id, @rownum := @rownum + 1 as rownum from sakila.actor limit 3; |
actor_id | rownum |
---|---|
1 | 1 |
2 | 2 |
3 | 3 |
得到的结果也许看起来没什么意义,这是因为主键是从1自增的,因此行号和主键值是一样的。但是,这种方式可以用于做排序。例如需要查询饰演电影数量最多的前10名演员,通常的做法是像下面这样写:
|
select actor_id, count (*) as cnt from sakila.film_actor group by actor_id order by cnt desc limit 10; |
得到的结果也许看起来没什么意义,这是因为主键是从1自增的,因此行号和主键值是一样的。但是,这种方式可以用于做排序。例如需要查询饰演电影数量最多的前10名演员,通常的做法是像下面这样写:
|
select actor_id, count (*) as cnt from sakila.film_actor group by actor_id order by cnt desc limit 10; |
如果我们要获得相应的排名值的话,则可以引入变量来完成:
|
set @curr_cnt := 0, @prev_cnt := 0, @rank := 0; select actor_id, @curr_cnt := cnt as cnt, @rank := if(@prev_cnt <> @curr_cnt, @rank+1, @rank) as rank, @prev_cnt := @curr_cnt as dummy from ( select actor_id, count (*) as cnt from sakila.film_actor group by actor_id order by cnt desc limit 10 ) as der; |
这里是将饰演电影的数量赋值给了 curr_cnt 变量,使用了prev_cnt 存储前一个演员的参演数量。排名从第一名开始的,如果后面的演员的数量和前一个演员的数量不同,则排名要往下(+1),如果相同则和前一个演员的排名相同。通过这种方式可以直接从查询结果中得到演员的排名,而不需要再从数据库查询做二次处理(当然也可以通过程序代码实现)。
避免重复获取刚刚修改的数据行
如果想在更新数据行的时候再重新获取数据行的信息,往往需要再读取一次数据库。这是因为 mysql 不像 postgresql 的 update returning 功能可以同时返回更新后的数据行,而只是返回更新影响的行数。但是,我们可以通过自定义变量完成这样的操作。例如,获取刚刚被修改过更新时间的行,不使用自定义变量的话需要做一次额外的查询:
|
update tb1 set lastupdated = now() where id = 1; select lastupdated from tb1 where id = 1; |
而使用自定义变量的时候可以避免这种情况:
|
update tb1 set lastupdated = now() where id = 1 and @now := now(); select @now; |
虽然还是有一个查询操作,但是后面的查询操作不再需要访问数据库了。
懒加载的联合查询
假设我们需要写一个联合查询完成如下任务:在联合的分支上查找匹配的数据行,如果找到了就跳过其他分支。y这种情况发生在需要从热区数据或低频访问数据中查找(比如近期订单和历史订单)。这是下面针对用户查询的一个普通的 sql:
|
select id from users where id = 123 union all select id from users_archived where id = 123; |
这个查询会先从当前正在使用的用户表查询 id 为123的用户,然后 在从已归档的用户表找同样 id 的用户。但是,这种写法比较低效,即便是在 users 表找到了想要找的用户,还是需要从users_archived 这个表再找一次,而实际用户 id 为123的只会存在其中的一张表中或两张表的数据是一样的。通过懒加载的联合查询,可以避免这种情况——只有在第一个分支没有找到数据时才进行第二个分支的查询。因此可以使用 mysql 的 greatest 方法来作为查询结果的容器以避免多返回数据列。
|
select greatest(@found := -1, id) as id, users. name , 'users' as which_tb1 from users where id = 123 union all select id, users_archived. name , 'users_archived' from users_archived where id = 123 and @found is null union all select 1, '' , 'reset' from dual where ( @found := null ) is not null ; |
上述的查询如果第一行有结果,则@found 不会被赋值,因而是 null,从而执行第二次查询。而第三次的 union 实际没什么效果,只是为了将@found恢复到 null 值,以便这段 sql 可以重复执行。另一个验证的方法是对同一张表进行这样的操作,可以发现实际只会返回一行数据或不返回数据(查询不到数据时)。
|
select greatest(@found := -1, `id`) as `id`, `infocenter_city`.` name `, 'city' as which_tb1 from `infocenter_city` where `id` = 460100 union all select `id`, `infocenter_city`.` name `, 'infocenter_city' from `infocenter_city` where id = 460100 and @found is null union all select 1, '' , 'reset' from dual where ( @found := null ) is not null |
以上就是mysql 使用自定义变量进行查询优化的详细内容,更多关于mysql 用自定义变量进行查询优化的资料请关注开心学习网其它相关文章!
- mysql拆分字符串(MySQL 字符串拆分操作含分隔符的字符串截取)
- mac的mysql连接问题如何解决(MAC 中mysql密码忘记解决办法)
- 阿里云mysql配置升级注意事项(详解如何在阿里云上安装mysql)
- 怎么把csv文件导入mysql(mysql导入csv的4种报错的解决方法)
- mysql触发器怎么添加(MySQL触发器的使用场景及方法实例)
- mysql各种锁详解(MySQL 查看事务和锁情况的常用语句分享)
- mysql高级概念(MySQL 自定义变量的概念及特点)
- mysql为什么优选innodb(如何区分MySQL的innodb_flush_log_at_trx_commit和sync_binlog)
- mysql语句详解(详解记录MySQL中lower_case_table_names的坑)
- phpstudymysql启动又自动停止(Win下解决phpStudy MySQL启动失败)
- mysql中自增字段类型(MySQL数字类型自增的坑)
- 怎么查看mysql运行日志(通过Query Profiler查看MySQL语句运行时间的操作方法)
- mysql模糊查询语句(mysql中like % %模糊查询的实现)
- mysql整体架构设计(MySQL 整体架构介绍)
- mysql char和varchar区别(MySQL CHAR和VARCHAR存储、读取时的差别)
- mysql读写分离怎么做(MySQL读写分离,写完读不到问题如何解决)
- 终于来了,淘宝更改账户名测试中,快去看看你能不能修改(淘宝更改账户名测试中)
- 淘宝支持账号名修改,网友 终于可以 重新做人 了(淘宝支持账号名修改)
- 盘点那些年让人称奇的年终奖 最后一个赢辣条毫无悬念(盘点那些年让人称奇的年终奖)
- 你还没有升职吗 他竟因为几套激励理论,升职了(你还没有升职吗)
- 某知名企业绩效管理体系及薪酬分配体系操作手册(某知名企业绩效管理体系及薪酬分配体系操作手册)
- 职场人改不掉这4个习惯,只会越混越穷,一辈子也翻不了身(职场人改不掉这4个习惯)
热门推荐
- css flex布局教程(详解CSS3伸缩布局盒模型Flex布局)
- laravel怎么同时连接数据库(Laravel框架实现多个视图共享相同数据的方法详解)
- css3 图片边框(css3图片边框border-image的用法)
- 自建FTP服务器并远程外网访问,花生棒自带端口映射3步搞定(自建FTP服务器并远程外网访问,花生棒自带端口映射3步搞定)
- javascript构造重复数组(JavaScript平铺数组转树形结构的实现示例)
- linux lnmp安装教程(LNMP系列教程之 SSL安装WordPress博客程序下载与安装)
- sqlserver字符串截取填充(SQL Server实现split函数分割字符串功能及用法示例)
- python操作sql server数据库(Python 数据库操作 SQLAlchemy的示例代码)
- sqlserver修改排序规则几种方法(SQL Server 分页编号的另一种方式推荐)
- docker 构建整个环境(Docker如何快速搭建LNMP环境最新)
排行榜
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9