sqlwith性能
⑴ sql server with as 能提高性能吗
使用WITHAS提高性能简化嵌套SQL
一.WITHAS的含义
WITHAS短语,也叫做子查询部分(subqueryfactoring),可以让你做很多事情,定义一个SQL片断,该SQL片断会
被整个SQL语句所用到。有的时候,是为了让SQL语句的可读性更高些,也有可能是在UNIONALL的不同部分,作为提供数
据的部分。
特别对于UNIONALL比较有用。因为UNIONALL的每个部分可能相同,但是如果每个部分都去执行一遍的话,则成本太高,
所以可以使用WITHAS短语,则只要执行一遍即可。如果WITHAS短语所定义的表名被调用两次以上,则优化器会自动将
WITHAS短语所获取的数据放入一个TEMP表里,如果只是被调用一次,则不会。而提示materialize则是强制将WITHAS
短语里的数据放入一个全局临时表里。很多查询通过这种方法都可以提高速度。
二.使用方法
先看下面一个嵌套的查询语句:
select*fromperson.
(.CountryRegionwhereNamelike'C%')上面的查询语句使用了一个子查询。虽然这条SQL语句并不复杂,但如果嵌套的层次过多,会使SQL语句非常难以阅
读和维护。因此,也可以使用表变量的方式来解决这个问题。
SQL语句如下:
declare@ttable(CountryRegionCodenvarchar(3))
insertinto@t(CountryRegionCode)(.CountryRegionwhereNamelike'C%')
select*fromperson.
in(select*from@t)
虽然上面的SQL语句要比第一种方式更复杂,但却将子查询放在了表变量@t中,这样做将使SQL语句更容易维护,但又
会带来另一个问题,就是性能的损失。由于表变量实际上使用了临时表,从而增加了额外的I/O开销,因此,表变量的方式
并不太适合数据量大且频繁查询的情况。为此,在SQLServer2005中提供了另外一种解决方案,这就是公用表表达式(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
cras
(
.CountryRegionwhereNamelike'C%'
)
select*fromperson.(select*fromcr)
其中cr是一个公用表表达式,该表达式在使用上与表变量类似,只是SQLServer2005在处理公用表表达式的方式上有
所不同。
在使用CTE时应注意如下几点:
1.CTE后面必须直接跟使用CTE的SQL语句(如select、insert、update等),否则,CTE将失效。如下面的SQL语句将无法正
常使用CTE:
with
cras
(
.CountryRegionwhereNamelike'C%'
)
select*fromperson.CountryRegion--应将这条SQL语句去掉
--使用CTE的SQL语句应紧跟在相关的CTE后面--
select*fromperson.(select*fromcr)
2.CTE后面也可以跟其他的CTE,但只能使用一个with,多个CTE中间用逗号(,)分隔,如下面的SQL语句所示:
with
cte1as
(
select*fromtable1wherenamelike'abc%'
),
cte2as
(
select*fromtable2whereid>20
),
cte3as
(
select*fromtable3whereprice<100
)
selecta.*fromcte1a,cte2b,cte3cwherea.id=b.idanda.id=c.id
3.如果CTE的表达式名称与某个数据表或视图重名,则紧跟在该CTE后面的SQL语句使用的仍然是CTE,当然,后面的SQL语句
使用的就是数据表或视图了,如下面的SQL语句所示:
--table1是一个实际存在的表
with
table1as
(
select*frompersonswhereage<30
)
select*fromtable1--使用了名为table1的公共表表达式
select*fromtable1--使用了名为table1的数据表
4.CTE可以引用自身,也可以引用在同一WITH子句中预先定义的CTE。不允许前向引用。
5.不能在CTE_query_definition中使用以下子句:
(1)COMPUTE或COMPUTEBY
(2)ORDERBY(除非指定了TOP子句)
(3)INTO
(4)带有查询提示的OPTION子句
(5)FORXML
(6)FORBROWSE
6.如果将CTE用在属于批处理的一部分的语句中,那么在它之前的语句必须以分号结尾,如下面的SQL所示:
declare@snvarchar(3)
set@s='C%'
;--必须加分号
with
t_treeas
(
.CountryRegionwhereNamelike@s
)
select*fromperson.(select*fromt_tree)
⑵ sql server 中 如何有效的提高性能
特别说明 在微软的SQL Server系统中通过有效的使用索引可以提高数据库的查询性能,但是性能的提高取决于数据库的实现。在本文中将会告诉你如何实现索引并有效的提高数据库的性能。 在关系型数据库中使用索引能够提高数据库性能,这一点是非常明显的。用的索引越多,从数据库系统中得到数据的速度就越快。然而,需要注意的是,用的索引越多,向数据库系统中插入新数据所花费的时间就越多。在本文中,你将了解到微软的SQL Server数据库所支持的各种不同类型的索引,在这里你将了解到如何使用不同的方法来实现索引,通过这些不同的实现方法,你在数据库的读性能方面得到的远比在数据库的整体性能方面的损失要多得多。 索引的定义 索引是数据库的工具,通过使用索引,在数据库中获取数据的时候,就可以不用扫描数据库中的所有数据记录,这样能够提高系统获取数据的性能。使用索引可以改变数据的组织方式,使得所有的数据都是按照相似的结构来组织的,这样就可以很容易地实现数据的检索访问。索引是按照列来创建的,这样就可以根据索引列中的值来帮助数据库找到相应的数据。 索引的类型 微软的SQL Server 支持两种类型的索引:clustered 索引和nonclustered索引。Clustered 索引在数据表中按照物理顺序存储数据。因为在表中只有一个物理顺序,所以在每个表中只能有一个clustered索引。在查找某个范围内的数据时,Clustered索引是一种非常有效的索引,因为这些数据在存储的时候已经按照物理顺序排好序了。 Nonclustered索引不会影响到下面的物理存储,但是它是由数据行指针构成的。如果已经存在一个clustered索引,在nonclustered中的索引指针将包含clustered索引的位置参考。这些索引比数据更紧促,而且对这些索引的扫描速度比对实际的数据表扫描要快得多。 如何实现索引 数据库可以自动创建某些索引。例如,微软的SQL Server系统通过自动创建唯一索引来强制实现UNIQUE约束,这样可以确保在数据库中不会插入重复数据。也可以使用CREATE INDEX语句或者通过SQL Server Enterprise Manager来创建其他索引,SQL Server Enterprise Manager还有一个索引创建模板来指导你如何创建索引。 得到更好的性能 虽然索引可以带来性能上的优势,但是同时也将带来一定的代价。虽然SQL Server系统允许你在每个数据表中创建多达256个nonclustered索引,但是建议不要使用这么多的索引。因为索引需要在内存和物理磁盘驱动器上使用更多的存储空间。在执行插入声明的过程中可能会在一定程度上导致系统性能的下降,因为在插入数据的时候是需要根据索引的顺序插入,而不是在第一个可用的位置直接插入数据,这样一来,存在的索引越多将导致插入或者更新声明所需要的时间就越多。 在使用SQL Server系统创建索引的时候,建议参照下面的创建准则来实现: 正确的选择数据类型 在索引中使用某些数据类型可以提高数据库系统的效率,例如,Int,bigint, smallint,和tinyint等这些数据类型都非常适合于用在索引中,因为他们都占用相同大小的空间并且可以很容易地实现比较操作。其他的数据类型如char和varchar的效率都非常低,因为这些数据类型都不适合于执行数学操作,并且执行比较操作的时间都比上面提到数据类型要长。 确保在使用的过程中正确的利用索引值 在执行查询操作时,可能所使用的列只是clustered的一部分,这时尤其要注意的是如何使用这些数据。当用这些数据列作为参数调用函数时,这些函数可能会使现有的排序优势失效。例如,使用日期值作为索引,而为了实现比较操作,可能需要将这个日期值转换为字符串,这样将导致在查询过程中无法用到这个日期索引值。 在创建多列索引时,需要注意列的顺序 数据库将根据第一列索引的值来排列记录,然后进一步根据第二列的值来排序,依次排序直到最后一个索引排序完毕。哪一列唯一数据值较少,哪一列就应该为第一个索引,这样可以确保数据可以通过索引进一步交叉排序。 在clustered索引中限制列的数量 在clustered索引中用到的列越多,在nonclustered索引中包含的clustered索引参考位置就越多,需要存储的数据也就越多。这样将增加包含索引的数据表的大小,并且将增加基于索引的搜索时间。 避免频繁更新clustered索引数据列 由于nonclustered 索引依赖于clustered 索引,所以如果构成clustered 索引的数据列频繁更新,将导致在nonclustered中存储的行定位器也将随之频繁更新。对于所有与这些列相关的查询来说,如果发生记录被锁定的情况时,这将可能导致性能成本的增加。 分开操作(如果可能的话) 对于一个表来说,如果需要进行频繁的执行插入、更新操作,同时还有大量读操作的话,在可能的情况下尝试将这个表分开操作。所有的插入和更新操作可以在一个没有索引的表中操作,然后将其复制到另外一个表中,在这个表里有大量的索引可以优化读数据的能力。 适当的重建索引 Nonclustered索引包含clustered索引的指针,这样一来Nonclustered索引将从属于clustered 索引。当重建clustered索引时,首先是丢弃原来的索引,然后再使用CREATE INDEX 来创建索引,或者在使用CREATE INDEX 声明的同时将DROP_EXISTING 子句作为重建索引的一部分。将丢弃和创建分为几步将会导致多次重建nonclustered 索引,而不象使用DROP_EXISTING 子句那样,只重建一次nonclustered 索引。 明智的使用填充因子 数据存储在那些具有固定大小的连续内存页面内。随着新的记录行的加入,数据内存页将逐渐被填满,系统就必须执行数据页的拆分工作,通过这个拆分工作将部分数据转移到下一个新的页面当中。这样的拆分之后,将加重系统的负担,并且会导致存储的数据支离破碎。填充因子可以维护数据之间的缺口,一般在创建索引的时候,该索引的填充因子就已经被设置好了。这样一来,可以减少插入数据所引起的页面分裂的次数。因为只是在创建索引的时候才维护空间的大小,在增加数据或者更新数据时不会去维护空间的大小。因此,要想能够充分的利用填充因子,就必须周期性的重建索引。由填充因子所造成的缺口将导致读性能的下降,因为随着数据库的扩张,越来越多的磁盘存取工作需要读取数据。所以,在读的次数超过写的次数的时候,很重要的一点是考虑使用填充因子还是使用缺省方式合适。 管理层的决策 通过有效的使用索引,可以在微软的SQL Server系统中实现很好的查询功能,但是使用索引的效率取决于几种不同的实现决策。在索引的性能平衡方面,要做出正确的数据库管理决策意味着需要在良好的性能和困境中抉择。在特定的情况下,本文给出的一些建议将有助于你做出正确的决策。
⑶ 这个sql如何优化性能,内附详细sql
crm_contract_details 的 contractid 有索引吗?
把各个连接条件涉及到的列,都检查一下有没有索引吧。
看样子应该是没有什么太好的办法。
你的 contract 表的 数据量似乎很大,是什么级别的? 在查询中也没有对 contract 表进行筛选。
所以这个表的 全表扫描 似乎是不可避免的。
⑷ 请帮忙分析这个sql语句的性能,现在查询很慢,哪里需要进行优化 表中数据是百万级的,索引情况未知
1、area_code in (...) 可以改成 join或 exist试试
2、t02的from中的 order by his.GATHER_DATE, his.USER_NAME可以去了,无用的排序
3、t02的开窗函数是否可以改成 GATHER_DATE=(select max(GATHER_DATE) from t1 where t1.username=t2.username)形式,不过这都是需要看执行计划
4、 order by t01.PUSH_DATE,
t01.TAG_USERNAME
)
WHERE rn > 0 5 6
AND rn <= 20000 7 这个order by不应该放在子查询里,排序的记录多呀,可以放到最外边来
⑸ 关于sql性能问题
WITH AS短语,也叫做子查询部分(subquery factoring),可以让你做很多事情,定义一个SQL片断,该SQL片断会
被整个SQL语句所用到。有的时候,是为了让SQL语句的可读性更高些,也有可能是在UNION ALL的不同部分,作为提供数
据的部分。
特别对于UNION ALL比较有用。因为UNION ALL的每个部分可能相同,但是如果每个部分都去执行一遍的话,则成本太高,
所以可以使用WITH AS短语,则只要执行一遍即可。如果WITH AS短语所定义的表名被调用两次以上,则优化器会自动将
WITH AS短语所获取的数据放入一个TEMP表里,如果只是被调用一次,则不会。而提示materialize则是强制将WITH AS
短语里的数据放入一个全局临时表里。很多查询通过这种方法都可以提高速度。
后者性能其实差不多,但是with as 好维护,可读性也好很多
⑹ SQL数据库性能和数据库调优
连接数量有三种方法查看 1.通过系统的逗性能地来查看: 开始->管理工具->性能(或者是运行里面输入 mmc)然后通过 添加计数器添加 SQL 的常用统计 然后在下面列出的项目里面选择用户连接就可以时时查询到sql server数据库连接数了。 不过此方法的话需要有访问那台计算机的权限,就是要通过windows账户登陆进去才可以添加此计数器。 2.通过系统表来查询: SELECT * FROM [Master].[dbo].[SYSPROCESSES] WHERE [DBID] IN ( SELECT [DBID] FROM [Master].[dbo].[SYSDATABASES] WHERE NAME='databaseName' ) databaseName 是需要查看的数据库,然后查询出来的行数,就是当前的sql server数据库连接数。不过里面还有一些别的状态可以做参考用。 3.通过系统过程来查询: SP_WHO 'loginName' loginName 是当然登陆Sql的用户名,一般程序里面都会使用一个username来登陆SQL这样通过这个用户名就能查看到此用户名登陆之后占用的连接了。 如果不写loginName,那么返回的就是所有的sql server数据库连接。 至于如何改善数据库性能,就是属于数据库调优方面的工作了,通常有以下几种调优方法: 1 查看数据库中造成数据库访问变慢的语句,通常是执行数量较多,执行速度慢的语句,对这些语句进行执行计划分析,并重写语句来优化,最常见的就是not in语句使用外连接语句代替; 2 根据语句中查询访问条件中的谓词,创建对应的索引,以提高查询的执行效率; 3 在数据存储上优化,将数据文件根据某个频繁访问属性的属性值进行水平分片,提高对应表的访问效率(oracle支持,sql server2000没有此功能) 4 重新设计业务逻辑结构,避免执行代价高的查询语句 5 服务器和数据库软件的能力终究还是有限的,无论如何优化当达到一定的访问数量是还是会超出负载,此时就需要考虑可扩展规模的分布式并行数据存储架构了。
⑺ 如何进行SQL性能优化
这里分享下mysql优化的几种方法。
1、首先在打开的软件中,需要分别为每一个表创建 InnoDB FILE的文件。
⑻ SQL 语句 优化 性能提升
经常见到有新手写出这样的语句。本质上是没有想清楚要查询什么数据。
其实,只要转换一下思路,用连接来完成就行了。不要用这么多in和not in。
目的就是直接查你想要的东西,而不要把不想要的东西都查出来,再用in和not in过滤掉。
这无异于把整个图书馆的书都搬回家,然后留下一本之后其他的又都送回去一样。累死数据库不偿命啊。
⑼ 如何测试sql语句性能,提高执行效率,sql2008
一段SQL代码写好以后,可以通过查看SQL的执行计划,初步预测该SQL在运行时的性能好坏,尤其是在发现某个SQL语句的效率较差时,我们可以通过查看执行计划,分析出该SQL代码的问题所在。 1、 打开熟悉的查看工具:PL/SQL Developer。 在PL/SQL Developer中写好一段SQL代码后,按F5,PL/SQL Developer会自动打开执行计划窗口,显示该SQL的执行计划。 2、 查看总COST,获得资源耗费的总体印象 一般而言,执行计划第一行所对应的COST(即成本耗费)值,反应了运行这段SQL的总体估计成本,单看这个总成本没有实际意义,但可以拿它与相同逻辑不同执行计划的SQL的总体COST进行比较,通常COST低的执行计划要好一些。 3、 按照从左至右,从上至下的方法,了解执行计划的执行步骤 执行计划按照层次逐步缩进,从左至右看,缩进最多的那一步,最先执行,如果缩进量相同,则按照从上而下的方法判断执行顺序,可粗略认为上面的步骤优先执行。每一个执行步骤都有对应的COST,可从单步COST的高低,以及单步的估计结果集(对应ROWS/基数),来分析表的访问方式,连接顺序以及连接方式是否合理。 4、 分析表的访问方式 表的访问方式主要是两种:全表扫描(TABLE ACCESS FULL)和索引扫描(INDEX SCAN),如果表上存在选择性很好的索引,却走了全表扫描,而且是大表的全表扫描,就说明表的访问方式可能存在问题;若大表上没有合适的索引而走了全表扫描,就需要分析能否建立索引,或者是否能选择更合适的表连接方式和连接顺序以提高效率。 5、 分析表的连接方式和连接顺序 表的连接顺序:就是以哪张表作为驱动表来连接其他表的先后访问顺序。 表的连接方式:简单来讲,就是两个表获得满足条件的数据时的连接过程。主要有三种表连接方式,嵌套循环(NESTED LOOPS)、哈希连接(HASH JOIN)和排序-合并连接(SORT MERGE JOIN)。我们常见得是嵌套循环和哈希连接。 嵌套循环:最适用也是最简单的连接方式。类似于用两层循环处理两个游标,外层游标称作驱动表,Oracle检索驱动表的数据,一条一条的代入内层游标,查找满足WHERE条件的所有数据,因此内层游标表中可用索引的选择性越好,嵌套循环连接的性能就越高。 哈希连接:先将驱动表的数据按照条件字段以散列的方式放入内存,然后在内存中匹配满足条件的行。哈希连接需要有合适的内存,而且必须在CBO优化模式下,连接两表的WHERE条件有等号的情况下才可以使用。哈希连接在表的数据量较大,表中没有合适的索引可用时比嵌套循环的效率要高。
⑽ 如何进行SQL性能优化
这里分享下mysql优化的几种方法。
1、首先在打开的软件中,需要分别为每一个表创建 InnoDB FILE的文件。