关闭 x
IT技术网
    技 采 号
    ITJS.cn - 技术改变世界
    • 实用工具
    • 菜鸟教程
    IT采购网 中国存储网 科技号 CIO智库

    IT技术网

    IT采购网
    • 首页
    • 行业资讯
    • 系统运维
      • 操作系统
        • Windows
        • Linux
        • Mac OS
      • 数据库
        • MySQL
        • Oracle
        • SQL Server
      • 网站建设
    • 人工智能
    • 半导体芯片
    • 笔记本电脑
    • 智能手机
    • 智能汽车
    • 编程语言
    IT技术网 - ITJS.CN
    首页 » SQL语言 »CTE和WITH AS短语结合使用提高SQL查询性能(1)

    CTE和WITH AS短语结合使用提高SQL查询性能(1)

    2011-07-08 17:49:00 出处:ITJS
    分享

    WITH AS短语,也叫做子查询部分(subquery factoring),可以让你做很多事情,定义一个SQL片断,该SQL片断会被整个SQL语句所用到。有的时候,是为了让SQL语句的可读性更高些,也有可能是在UNION ALL的不同部分,作为提供数据的部分。

    特别对于UNION ALL比较有用。因为UNION ALL的每个部分可能相同,但是假如每个部分都去执行一遍的话,则成本太高,所以可以使用WITH AS短语,则只要执行一遍即可。假如WITH AS短语所定义的表名被调用两次以上,则优化器会自动将WITH AS短语所获取的数据放入一个TEMP表里,假如只是被调用一次,则不会。而提示materialize则是强制将WITH AS短语里的数据放入一个全局临时表里。很多查询通过这种方法都可以提高速度。

    使用方法:

    先看下面一个嵌套的查询语句:

    select * from person.StateProvince where CountryRegionCode in   (select CountryRegionCode from person.CountryRegion where Name like 'C%') 

    上面的查询语句使用了一个子查询。虽然这条SQL语句并不复杂,但假如嵌套的层次过多,会使SQL语句非常难以阅读和维护。因此,也可以使用表变量的方式来解决这个问题,SQL语句如下:

    declare @t table(CountryRegionCode nvarchar(3))   insert into @t(CountryRegionCode)  (select CountryRegionCode from person.CountryRegion where Name like 'C%')   select * from person.StateProvince where CountryRegionCode   in (select * from @t) 

    虽然上面的SQL语句要比第一种方式更复杂,但却将子查询放在了表变量@t中,这样做将使SQL语句更容易维护,但又会带来另一个问题,就是性能的损失。由于表变量实际上使用了临时表,从而增加了额外的I/O开销,因此,表变量的方式并不太适合数据量大且频繁查询的情况。为此,在SQL Server 2005中提供了另外一种解决方案,这就是公用表表达式(CTE),使用CTE,可以使SQL语句的可维护性,同时,CTE要比表变量的效率高得多。

    下面是CTE的语法:

    [ WITH <common_table_expression> [ ,n ] ]   <common_table_expression>::=   expression_name [ ( column_name [ ,n ] ) ]   AS   ( CTE_query_definition ) 

    现在使用CTE来解决上面的问题,SQL语句如下:

    with   cr as   (   select CountryRegionCode from person.CountryRegion where Name like 'C%'   )   select * from person.StateProvince where CountryRegionCode in (select * from cr) 

    其中cr是一个公用表表达式,该表达式在使用上与表变量类似,只是SQL Server 2005在处理公用表表达式的方式上有所不同。

    在使用CTE时应注意如下几点:

    1. CTE后面必须直接跟使用CTE的SQL语句(如select、insert、update等),否则,CTE将失效。如下面的SQL语句将无法正常使用CTE:

    with   cr as   (   select CountryRegionCode from person.CountryRegion where Name like 'C%'   ) 

    select * from person.CountryRegion 应将这条SQL语句去掉。

    使用CTE的SQL语句应紧跟在相关的CTE后面:

    select * from person.StateProvince where CountryRegionCode in (select * from cr) 

    2. CTE后面也可以跟其他的CTE,但只能使用一个with,多个CTE中间用逗号(,)分隔,如下面的SQL语句所示:

    with   cte1 as   (   select * from table1 where name like 'abc%'   ),   cte2 as   (   select * from table2 where id > 20   ),   cte3 as   (   select * from table3 where price < 100  )   select a.* from cte1 a, cte2 b, cte3 c where a.id = b.id and a.id = c.id 

    3. 假如CTE的表达式名称与某个数据表或视图重名,则紧跟在该CTE后面的SQL语句使用的仍然是CTE,当然,后面的SQL语句使用的就是数据表或视图了,如下面的SQL语句所示:

    table1是一个实际存在的表:

    with   table1 as   (   select * from persons where age < 30  )   select * from table1  --  使用了名为table1的公共表表达式   select * from table1  --  使用了名为table1的数据表 

    4. CTE 可以引用自身,也可以引用在同一 WITH 子句中预先定义的CTE。不允许前向引用。

    5. 不能在 CTE_query_definition 中使用以下子句:

    (1)COMPUTE 或 COMPUTE BY

    (2)ORDER BY(除非指定了 TOP 子句)

    (3)INTO

    (4)带有查询提示的 OPTION 子句

    (5)FOR XML

    (6)FOR BROWSE

    6. 假如将 CTE 用在属于批处理的一部分的语句中,那么在它之前的语句必须以分号结尾,如下面的SQL所示:

    declare @s nvarchar(3)   set @s = 'C%';  -- 必须加分号   with   t_tree as   (   select CountryRegionCode from person.CountryRegion where Name like @s   )   select * from person.StateProvince where CountryRegionCode in (select * from t_tree) 

    本文就介绍到这里,希望会对大家有所帮助。

    WITH AS短语,也叫做子查询部分(subquery factoring),可以让你做很多事情,定义一个SQL片断,该SQL片断会被整个SQL语句所用到。有的时候,是为了让SQL语句的可读性更高些,也有可能是在UNION ALL的不同部分,作为提供数据的部分。

    特别对于UNION ALL比较有用。因为UNION ALL的每个部分可能相同,但是假如每个部分都去执行一遍的话,则成本太高,所以可以使用WITH AS短语,则只要执行一遍即可。假如WITH AS短语所定义的表名被调用两次以上,则优化器会自动将WITH AS短语所获取的数据放入一个TEMP表里,假如只是被调用一次,则不会。而提示materialize则是强制将WITH AS短语里的数据放入一个全局临时表里。很多查询通过这种方法都可以提高速度。

    使用方法:

    先看下面一个嵌套的查询语句:

    select * from person.StateProvince where CountryRegionCode in   (select CountryRegionCode from person.CountryRegion where Name like 'C%') 

    上面的查询语句使用了一个子查询。虽然这条SQL语句并不复杂,但假如嵌套的层次过多,会使SQL语句非常难以阅读和维护。因此,也可以使用表变量的方式来解决这个问题,SQL语句如下:

    declare @t table(CountryRegionCode nvarchar(3))   insert into @t(CountryRegionCode)  (select CountryRegionCode from person.CountryRegion where Name like 'C%')   select * from person.StateProvince where CountryRegionCode   in (select * from @t) 

    虽然上面的SQL语句要比第一种方式更复杂,但却将子查询放在了表变量@t中,这样做将使SQL语句更容易维护,但又会带来另一个问题,就是性能的损失。由于表变量实际上使用了临时表,从而增加了额外的I/O开销,因此,表变量的方式并不太适合数据量大且频繁查询的情况。为此,在SQL Server 2005中提供了另外一种解决方案,这就是公用表表达式(CTE),使用CTE,可以使SQL语句的可维护性,同时,CTE要比表变量的效率高得多。

    下面是CTE的语法:

    [ WITH <common_table_expression> [ ,n ] ]   <common_table_expression>::=   expression_name [ ( column_name [ ,n ] ) ]   AS   ( CTE_query_definition ) 

    现在使用CTE来解决上面的问题,SQL语句如下:

    with   cr as   (   select CountryRegionCode from person.CountryRegion where Name like 'C%'   )   select * from person.StateProvince where CountryRegionCode in (select * from cr) 

    其中cr是一个公用表表达式,该表达式在使用上与表变量类似,只是SQL Server 2005在处理公用表表达式的方式上有所不同。

    在使用CTE时应注意如下几点:

    1. CTE后面必须直接跟使用CTE的SQL语句(如select、insert、update等),否则,CTE将失效。如下面的SQL语句将无法正常使用CTE:

    with   cr as   (   select CountryRegionCode from person.CountryRegion where Name like 'C%'   ) 

    select * from person.CountryRegion 应将这条SQL语句去掉。

    使用CTE的SQL语句应紧跟在相关的CTE后面:

    select * from person.StateProvince where CountryRegionCode in (select * from cr) 

    2. CTE后面也可以跟其他的CTE,但只能使用一个with,多个CTE中间用逗号(,)分隔,如下面的SQL语句所示:

    with   cte1 as   (   select * from table1 where name like 'abc%'   ),   cte2 as   (   select * from table2 where id > 20   ),   cte3 as   (   select * from table3 where price < 100  )   select a.* from cte1 a, cte2 b, cte3 c where a.id = b.id and a.id = c.id 

    3. 假如CTE的表达式名称与某个数据表或视图重名,则紧跟在该CTE后面的SQL语句使用的仍然是CTE,当然,后面的SQL语句使用的就是数据表或视图了,如下面的SQL语句所示:

    table1是一个实际存在的表:

    with   table1 as   (   select * from persons where age < 30  )   select * from table1  --  使用了名为table1的公共表表达式   select * from table1  --  使用了名为table1的数据表 

    4. CTE 可以引用自身,也可以引用在同一 WITH 子句中预先定义的CTE。不允许前向引用。

    5. 不能在 CTE_query_definition 中使用以下子句:

    (1)COMPUTE 或 COMPUTE BY

    (2)ORDER BY(除非指定了 TOP 子句)

    (3)INTO

    (4)带有查询提示的 OPTION 子句

    (5)FOR XML

    (6)FOR BROWSE

    6. 假如将 CTE 用在属于批处理的一部分的语句中,那么在它之前的语句必须以分号结尾,如下面的SQL所示:

    declare @s nvarchar(3)   set @s = 'C%';  -- 必须加分号   with   t_tree as   (   select CountryRegionCode from person.CountryRegion where Name like @s   )   select * from person.StateProvince where CountryRegionCode in (select * from t_tree) 

    本文就介绍到这里,希望会对大家有所帮助。

    上一篇返回首页 下一篇

    声明: 此文观点不代表本站立场;转载务必保留本文链接;版权疑问请联系我们。

    别人在看

    正版 Windows 11产品密钥怎么查找/查看?

    还有3个月,微软将停止 Windows 10 的更新

    Windows 10 终止支持后,企业为何要立即升级?

    Windows 10 将于 2025年10 月终止技术支持,建议迁移到 Windows 11

    Windows 12 发布推迟,微软正全力筹备Windows 11 25H2更新

    Linux 退出 mail的命令是什么

    Linux 提醒 No space left on device,但我的空间看起来还有不少空余呢

    hiberfil.sys文件可以删除吗?了解该文件并手把手教你删除C盘的hiberfil.sys文件

    Window 10和 Windows 11哪个好?答案是:看你自己的需求

    盗版软件成公司里的“隐形炸弹”?老板们的“法务噩梦” 有救了!

    IT头条

    公安部:我国在售汽车搭载的“智驾”系统都不具备“自动驾驶”功能

    02:03

    液冷服务器概念股走强,博汇、润泽等液冷概念股票大涨

    01:17

    亚太地区的 AI 驱动型医疗保健:2025 年及以后的下一步是什么?

    16:30

    智能手机市场风云:iPhone领跑销量榜,华为缺席引争议

    15:43

    大数据算法和“老师傅”经验叠加 智慧化收储粮食尽显“科技范”

    15:17

    技术热点

    SQL汉字转换为拼音的函数

    windows 7系统无法运行Photoshop CS3的解决方法

    巧用MySQL加密函数对Web网站敏感数据进行保护

    MySQL基础知识简介

    Windows7和WinXP下如何实现不输密码自动登录系统的设置方法介绍

    windows 7系统ip地址冲突怎么办?windows 7系统IP地址冲突问题的

      友情链接:
    • IT采购网
    • 科技号
    • 中国存储网
    • 存储网
    • 半导体联盟
    • 医疗软件网
    • 软件中国
    • ITbrand
    • 采购中国
    • CIO智库
    • 考研题库
    • 法务网
    • AI工具网
    • 电子芯片网
    • 安全库
    • 隐私保护
    • 版权申明
    • 联系我们
    IT技术网 版权所有 © 2020-2025,京ICP备14047533号-20,Power by OK设计网

    在上方输入关键词后,回车键 开始搜索。Esc键 取消该搜索窗口。