热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

mysql非相关子查询_mysql函数取代相关子查询(Correlatedsubquery)

CREATETABLE20121105_teacher(teacher_idint(11)NOTNULL,school_idint(11)NOTNULL,PRIMARYKEY(te

CREATE TABLE `20121105_teacher` (

`teacher_id` int(11) NOT NULL,

`school_id` int(11) NOT NULL,

PRIMARY KEY (`teacher_id`),

KEY `20121105_teacher_idx_school` (`school_id`)

) ENGINE=InnoDB

教师表,里面有1000个教师,随机分布在40个学校里

CREATE TABLE `20121105_subject_teacher_class` (

`teacher_id` int(11) NOT NULL,

`subj` varchar(10) NOT NULL,

`class` varchar(10) NOT NULL,

PRIMARY KEY (`teacher_id`,`subj`,`class`)

) ENGINE=InnoDB

教师任课科目表,教师随机在24个班级内随机教三个科目.为了方便演示,直接将科目名称和班级名称放到数据库中

假设要查询教师的授课情况,每个教师这样显示

英语:11班,12班,8班##语文:13班,1班,21班,6班##数学:12班,14班,6班,7班

很容易想到这个sql能把每个教师的授课情况显示出来

select tid,GROUP_CONCAT( cls SEPARATOR '##') c1 from

(

select teacher_id tid,CONCAT(subj,':',GROUP_CONCAT(class)) cls

from 20121105_subject_teacher_class stc

GROUP BY teacher_id,subj

) t GROUP BY tid,

那么把这个作为一个子查询呢?似乎很容易想到

select teacher_id,

(

select GROUP_CONCAT( cls SEPARATOR ' ## ') from

(

select teacher_id tid,CONCAT(subj,':',GROUP_CONCAT(class)) cls

from 20121105_subject_teacher_class stc where stc.teacher_id=t1.teacher_id

GROUP BY teacher_id,subj) t GROUP BY tid

)

from 20121105_teacher t1 where school_id=2

不过可惜在最里面那层子查询已经无法引用最外层的t1表的teacher_id这个字段了,

只能拿到外面一层

select teacher_id,

(

select GROUP_CONCAT( cls SEPARATOR ' ## ') from

(

select teacher_id tid,CONCAT(subj,':',GROUP_CONCAT(class)) cls

from 20121105_subject_teacher_class stc

GROUP BY teacher_id,subj) t where t.tid=t1.teacher_id GROUP BY tid

)

from 20121105_teacher t1 where school_id=2

不过因为这样无法高效利用索引,这个sql花了0.05s

所以可以建个函数

CREATE FUNCTION `20121105f`(p_teacher_id int) RETURNS varchar(2000)

READS SQL DATA

BEGIN

DECLARE v_result VARCHAR(2000);

DECLARE EXIT HANDLER for not found return null;

select GROUP_CONCAT( cls SEPARATOR ' ## ') into v_result from

(

select teacher_id tid,CONCAT(subj,':',GROUP_CONCAT(class)) cls

from 20121105_subject_teacher_class stc where stc.teacher_id=p_teacher_id

GROUP BY teacher_id,subj

) t GROUP BY tid;

return v_result;

END

然后这样用

select SQL_NO_CACHE teacher_id,

20121105f(teacher_id)

from 20121105_teacher t1 where school_id=2

马上成瞬时的了.

不用子查询,也可以用左连接的方法

select t1.teacher_id,t2.c1

from 20121105_teacher t1

left join (

select tid,GROUP_CONCAT( cls SEPARATOR '##') c1 from

(

select teacher_id tid,CONCAT(subj,':',GROUP_CONCAT(class)) cls

from 20121105_subject_teacher_class stc

GROUP BY teacher_id,subj

) t GROUP BY tid

) t2

on t1.teacher_id=t2.tid

where school_id=2

这种情况下因为20121105_subject_teacher_class表没用索引,是0.04s左右

加上条件

select t1.teacher_id,t2.c1

from 20121105_teacher t1

left join (

select tid,GROUP_CONCAT( cls SEPARATOR '##') c1 from

(

select stc.teacher_id tid,CONCAT(subj,':',GROUP_CONCAT(class)) cls

from 20121105_subject_teacher_class stc ,20121105_teacher te

where stc.teacher_id=te.teacher_id and te.school_id=2

GROUP BY stc.teacher_id,subj

) t GROUP BY tid

) t2

on t1.teacher_id=t2.tid

where school_id=2

这样这个也成了瞬时的,不过筛选teacher的条件(school_id=2)执行了两次,

如果这个条件比较耗资源,应该就更慢了

分享到:

18e900b8666ce6f233d25ec02f95ee59.png

72dd548719f0ace4d5f9bca64e1d7715.png

2012-11-05 16:07

浏览 1724

分类:数据库

评论



推荐阅读
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 本文介绍了如何在MySQL中将零值替换为先前的非零值的方法,包括使用内联查询和更新查询。同时还提供了选择正确值的方法。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 本文由编程笔记小编整理,介绍了PHP中的MySQL函数库及其常用函数,包括mysql_connect、mysql_error、mysql_select_db、mysql_query、mysql_affected_row、mysql_close等。希望对读者有一定的参考价值。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • Java String与StringBuffer的区别及其应用场景
    本文主要介绍了Java中String和StringBuffer的区别,String是不可变的,而StringBuffer是可变的。StringBuffer在进行字符串处理时不生成新的对象,内存使用上要优于String类。因此,在需要频繁对字符串进行修改的情况下,使用StringBuffer更加适合。同时,文章还介绍了String和StringBuffer的应用场景。 ... [详细]
  • 前景:当UI一个查询条件为多项选择,或录入多个条件的时候,比如查询所有名称里面包含以下动态条件,需要模糊查询里面每一项时比如是这样一个数组条件:newstring[]{兴业银行, ... [详细]
  • 一、Hadoop来历Hadoop的思想来源于Google在做搜索引擎的时候出现一个很大的问题就是这么多网页我如何才能以最快的速度来搜索到,由于这个问题Google发明 ... [详细]
  • 本文详细介绍了SQL日志收缩的方法,包括截断日志和删除不需要的旧日志记录。通过备份日志和使用DBCC SHRINKFILE命令可以实现日志的收缩。同时,还介绍了截断日志的原理和注意事项,包括不能截断事务日志的活动部分和MinLSN的确定方法。通过本文的方法,可以有效减小逻辑日志的大小,提高数据库的性能。 ... [详细]
  • 推荐一个ASP的内容管理框架(ASP Nuke)的优势和适用场景
    本文推荐了一个ASP的内容管理框架ASP Nuke,并介绍了其主要功能和特点。ASP Nuke支持文章新闻管理、投票、论坛等主要内容,并可以自定义模块。最新版本为0.8,虽然目前仍处于Alpha状态,但作者表示会继续更新完善。文章还分析了使用ASP的原因,包括ASP相对较小、易于部署和较简单等优势,适用于建立门户、网站的组织和小公司等场景。 ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 本文介绍了游标的使用方法,并以一个水果供应商数据库为例进行了说明。首先创建了一个名为fruits的表,包含了水果的id、供应商id、名称和价格等字段。然后使用游标查询了水果的名称和价格,并将结果输出。最后对游标进行了关闭操作。通过本文可以了解到游标在数据库操作中的应用。 ... [详细]
  • ALTERTABLE通过更改、添加、除去列和约束,或者通过启用或禁用约束和触发器来更改表的定义。语法ALTERTABLEtable{[ALTERCOLUMNcolu ... [详细]
author-avatar
wgsd325
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有