`
xcy13638760
  • 浏览: 52723 次
社区版块
存档分类
最新评论

SQL语句技巧

 
阅读更多
以下并非本人整理,但是看后感觉相当不错,特此分享。


1、应用程序中,保证在实现功能的基础上,尽量减少对数据库的访问次数;通过
搜索参数,尽量减少对表的访问行数,最小化结果集,从而减轻网络负担;能够分
开的操作尽量分开处理,提高每次的响应速度;在数据窗口使用SQL时,尽量把使
用的索引放在选择的首列;算法的结构尽量简单;在查询时,不要过多地使用通配
符如SELECT*FROMT1语句,要用到几列就选择几列如:SELECTCOL1,COL2FROM
T1;在可能的情况下尽量限制尽量结果集行数如:SELECTTOP300
COL1,COL2,COL3FROMT1,因为某些情况下用户是不需要那么多的数据的。不要在
应用中使用数据库游标,游标是非常有用的工具,但比使用常规的、面向集的SQL
语句需要更大的开销;按照特定顺序提取数据的查找。

2、避免使用不兼容的数据类型。例如float和int、char和varchar、binary和
varbinary是不兼容的。数据类型的不兼容可能使优化器无法执行一些本来可以进
行的优化操作。例如:
SELECTnameFROMemployeeWHEREsalary>60000
在这条语句中,如salary字段是money型的,则优化器很难对其进行优化,因为60000
是个整型数。我们应当在编程时将整型转化成为钱币型,而不要等到运行时转化。

3、尽量避免在WHERE子句中对字段进行函数或表达式操作,这将导致引擎放弃
使用索引而进行全表扫描。如:
SELECT*FROMT1WHEREF1/2=100
应改为:
SELECT*FROMT1WHEREF1=100*2

SELECT*FROMRECORDWHERESUBSTRING(CARD_NO,1,4)=’5378’
应改为:
SELECT*FROMRECORDWHERECARD_NOLIKE‘5378%’

SELECTmember_number,first_name,last_nameFROMmembers
WHEREDATEDIFF(yy,datofbirth,GETDATE())>21
应改为:
SELECTmember_number,first_name,last_nameFROMmembers
WHEREdateofbirth<DATEADD(yy,-21,GETDATE())
即:任何对列的操作都将导致表扫描,它包括数据库函数、计算表达式等等,查询
时要尽可能将操作移至等号右边。

4、避免使用!=或<>、ISNULL或ISNOTNULL、IN,NOTIN等这样的操作符,
因为这会使系统无法使用索引,而只能直接搜索表中的数据。例如:
SELECTidFROMemployeeWHEREid!='B%'
优化器将无法通过索引来确定将要命中的行数,因此需要搜索该表的所有行。

5、尽量使用数字型字段,一部分开发人员和数据库管理人员喜欢把包含数值信
息的字段
设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在
处理查询和连接回逐个比较字符串中每一个字符,而对于数字型而言只需要比较一
次就够了。

6、合理使用EXISTS,NOTEXISTS子句。如下所示:
1.SELECTSUM(T1.C1)FROMT1WHERE(
(SELECTCOUNT(*)FROMT2WHERET2.C2=T1.C2>0)
2.SELECTSUM(T1.C1)FROMT1WHEREEXISTS(
SELECT*FROMT2WHERET2.C2=T1.C2)
两者产生相同的结果,但是后者的效率显然要高于前者。因为后者不会产生大量锁
定的表扫描或是索引扫描。
如果你想校验表里是否存在某条纪录,不要用count(*)那样效率很低,而且浪费服
务器资源。可以用EXISTS代替。如:
IF(SELECTCOUNT(*)FROMtable_nameWHEREcolumn_name='xxx')
可以写成:
IFEXISTS(SELECT*FROMtable_nameWHEREcolumn_name='xxx')

经常需要写一个T_SQL语句比较一个父结果集和子结果集,从而找到是否存在在父
结果集中有而在子结果集中没有的记录,如:
1.SELECTa.hdr_keyFROMhdr_tbla----tbla表示tbl用别名a代替
WHERENOTEXISTS(SELECT*FROMdtl_tblbWHEREa.hdr_key=b.hdr_key)

2.SELECTa.hdr_keyFROMhdr_tbla
LEFTJOINdtl_tblbONa.hdr_key=b.hdr_keyWHEREb.hdr_keyISNULL

3.SELECThdr_keyFROMhdr_tbl
WHEREhdr_keyNOTIN(SELECThdr_keyFROMdtl_tbl)
三种写法都可以得到同样正确的结果,但是效率依次降低。

7、尽量避免在索引过的字符数据中,使用非打头字母搜索。这也使得引擎无法
利用索引。
见如下例子:
SELECT*FROMT1WHERENAMELIKE‘%L%’
SELECT*FROMT1WHERESUBSTING(NAME,2,1)=’L’
SELECT*FROMT1WHERENAMELIKE‘L%’
即使NAME字段建有索引,前两个查询依然无法利用索引完成加快操作,引擎不得不
对全表所有数据逐条操作来完成任务。而第三个查询能够使用索引来加快操作。

8、分利用连接条件,在某种情况下,两个表之间可能不只一个的连接条件,这
时在WHERE子句中将连接条件完整的写上,有可能大大提高查询速度。
例:
SELECTSUM(A.AMOUNT)FROMACCOUNTA,CARDBWHEREA.CARD_NO=B.CARD_NO
SELECTSUM(A.AMOUNT)FROMACCOUNTA,CARDBWHEREA.CARD_NO=B.CARD_NO
ANDA.ACCOUNT_NO=B.ACCOUNT_NO
第二句将比第一句执行快得多。

9、消除对大型表行数据的顺序存取
尽管在所有的检查列上都有索引,但某些形式的WHERE子句强迫优化器使用
顺序存取。如:
SELECT*FROMordersWHERE(customer_num=104ANDorder_num>1001)OR
order_num=1008
解决办法可以使用并集来避免顺序存取:
SELECT*FROMordersWHEREcustomer_num=104ANDorder_num>1001
UNION
SELECT*FROMordersWHEREorder_num=1008
这样就能利用索引路径处理查询。

10、避免困难的正规表达式
LIKE关键字支持通配符匹配,技术上叫正规表达式。但这种匹配特别耗费时
间。例如:SELECT*FROMcustomerWHEREzipcodeLIKE“98___”
即使在zipcode字段上建立了索引,在这种情况下也还是采用顺序扫描的方式。如
果把语句改为SELECT*FROMcustomerWHEREzipcode>“98000”,在执行查询
时就会利用索引来查询,显然会大大提高速度。
11、使用视图加速查询
把表的一个子集进行排序并创建视图,有时能加速查询。它有助于避免多重排序
操作,而且在其他方面还能简化优化器的工作。例如:
SELECTcust.name,rcvbles.balance,……othercolumns
FROMcust,rcvbles
WHEREcust.customer_id=rcvlbes.customer_id
ANDrcvblls.balance>0
ANDcust.postcode>“98000”
ORDERBYcust.name
如果这个查询要被执行多次而不止一次,可以把所有未付款的客户找出来放在一个
视图中,并按客户的名字进行排序:
CREATEVIEWDBO.V_CUST_RCVLBES
AS
SELECTcust.name,rcvbles.balance,……othercolumns
FROMcust,rcvbles
WHEREcust.customer_id=rcvlbes.customer_id
ANDrcvblls.balance>0
ORDERBYcust.name

然后以下面的方式在视图中查询:
SELECT*FROMV_CUST_RCVLBES
WHEREpostcode>“98000”
视图中的行要比主表中的行少,而且物理顺序就是所要求的顺序,减少了磁盘
I/O,所以查询工作量可以得到大幅减少。

12、能够用BETWEEN的就不要用IN
SELECT*FROMT1WHEREIDIN(10,11,12,13,14)
改成:
SELECT*FROMT1WHEREIDBETWEEN10AND14
因为IN会使系统无法使用索引,而只能直接搜索表中的数据。

13、DISTINCT的就不用GROUPBY
SELECTOrderIDFROMDetailsWHEREUnitPrice>10GROUPBYOrderID
可改为:
SELECTDISTINCTOrderIDFROMDetailsWHEREUnitPrice>10


14、部分利用索引
1.SELECTemployeeID,firstname,lastname
FROMnames
WHEREdept='prod'orcity='Orlando'ordivision='food'

2.SELECTemployeeID,firstname,lastnameFROMnamesWHEREdept=
'prod'
UNIONALL
SELECTemployeeID,firstname,lastnameFROMnamesWHEREcity='Orlando'
UNIONALL
SELECTemployeeID,firstname,lastnameFROMnamesWHEREdivision=
'food'
如果dept列建有索引则查询2可以部分利用索引,查询1则不能。

15、能用UNIONALL就不要用UNION
UNIONALL不执行SELECTDISTINCT函数,这样就会减少很多不必要的资源

16、不要写一些不做任何事的查询
如:SELECTCOL1FROMT1WHERE1=0
SELECTCOL1FROMT1WHERECOL1=1ANDCOL1=2
这类死码不会返回任何结果集,但是会消耗系统资源。

17、尽量不要用SELECTINTO语句。
SELECTINTO语句会导致表锁定,阻止其他用户访问该表。

18、必要时强制查询优化器使用某个索引
SELECT*FROMT1WHEREnextprocess=1ANDprocessidIN(8,32,45)
改成:
SELECT*FROMT1(INDEX=IX_ProcessID)WHEREnextprocess=1AND
processidIN(8,32,45)
则查询优化器将会强行利用索引IX_ProcessID执行查询。

19、虽然UPDATE、DELETE语句的写法基本固定,但是还是对UPDATE语句给点建
议:
a)尽量不要修改主键字段。
b)当修改VARCHAR型字段时,尽量使用相同长度内容的值代替。
c)尽量最小化对于含有UPDATE触发器的表的UPDATE操作。
d)避免UPDATE将要复制到其他数据库的列。
e)避免UPDATE建有很多索引的列。
f)避免UPDATE在WHERE子句条件中的列。


上面我们提到的是一些基本的提高查询速度的注意事项,但是在更多的情况下,往往
需要反复试验比较不同的语句以得到最佳方案。最好的方法当然是测试,看实现相
同功能的SQL语句哪个执行时间最少,但是数据库中如果数据量很少,是比较不出
来的,这时可以用查看执行计划,即:把实现相同功能的多条SQL语句考到查询分
析器,按CTRL+L看查所利用的索引,表扫描次数(这两个对性能影响最大),总体
上看询成本百分比即可。
简单的存储过程可以用向导自动生成:在企业管理器工具栏点击运行向导图标,点
击”数据库”、”创建存储过程向导”。复杂存储过程的调试:在查询分析器左边
的对象浏览器(没有?按F8)选择要调试的存储过程,点右键,点调试,输入参数
执行,出现一个浮动工具条,上面有单步执行,断点设置等。
分享到:
评论

相关推荐

    一些sql语句技巧及知识的汇总

    ### SQL语句技巧及知识汇总 #### 1. 转换日期格式 在SQL Server中,可以使用`CONVERT`函数将系统当前时间转换为特定格式的字符串。例如,`CONVERT(char(10), GETDATE(), 120)`将当前日期和时间转换为类似于`...

    SQL语句运用技巧

    ### SQL语句运用技巧 #### 一、SQL语言概述 SQL(Structured Query Language,结构化查询语言)是一种用于处理数据库的标准计算机语言。它允许用户在数据的高层次结构上操作而无需关心具体的存储细节。SQL的强大之...

    SQL 执行超长语句

    #### 三、编写高效合理的超长SQL语句技巧 1. **使用变量和临时表**:可以通过定义变量或创建临时表来简化复杂查询。例如,在进行多次查询时可以先将部分结果存储到临时表中,然后再进行后续处理。 2. **合理拆分...

    (SQL编程优化)配套SQL语句技巧

    ### SQL编程优化与技巧详解 ...通过对SQL语句的精心设计和优化,不仅可以显著提升查询性能,还能减少数据库系统的整体负载。实践中应结合具体情况灵活应用上述技巧,不断测试和调整以达到最佳效果。

    SQL语句技巧:按月统计数据

    SQL语句技巧:按月统计数据 在本文中,我们将探讨如何使用 SQL 语句来统计每个月的数据量。我们将使用一个示例表来演示如何使用 SQL 语句来实现这个功能。 表结构 我们的示例表结构如下所示: | qty | date | | ...

    经典sql语句大全(基础篇、提升篇、技巧篇)

    经典 SQL 语句大全 本资源为经典 SQL 语句大全,涵盖基础篇、提升篇和技巧篇三个部分,旨在提供全面、系统的 SQL 语句...本部分将涵盖更多的 SQL 语句技巧和高级查询运算词,旨在提供更加prehensive 的 SQL 语句知识。

    查看LINQ生成SQL语句的几种方法

    LINQ(Language Integrated Query,语言集成查询)是.NET...总之,掌握查看LINQ生成SQL语句的技巧对理解和优化数据库操作至关重要。通过这些方法,开发者可以更好地调试查询,找出性能瓶颈,并提升应用程序的整体效率。

    oracle监听执行sql语句

    ### Oracle监听执行SQL语句详解 #### 一、Oracle监听执行概述 在Oracle数据库管理与维护过程中,有时候我们需要了解应用程序正在执行哪些SQL语句,这不仅有助于性能优化,还可以帮助我们诊断潜在的问题。通过监听...

    sql语句、动态SQL语句基本语法

    在数据库管理系统(如MySQL、Oracle、SQL Server等)中,SQL语句是不可或缺的一部分。 1. SQL基础语法 SQL的基础语法包括SELECT、INSERT、UPDATE、DELETE四大语句,它们分别用于查询、插入、更新和删除数据。 - ...

    如何写出高效率的SQL语句--SQL优化技巧

    如何写出高效率的SQL语句--SQL优化技巧 SQL 优化技巧是提高数据库性能的关键所在。编写高效率的 SQL 语句需要对索引的机制有一定了解,以下是关于索引的知识点: 索引的优点和局限 索引可以提高查询的效率,但会...

    嵌入式SQL语句在VC++数据库系统开发中的技巧

    嵌入式SQL语句在VC++数据库系统开发中扮演着重要的角色,它允许开发者将SQL命令直接嵌入到C++程序中,实现高效且灵活的数据处理。本文将深入探讨嵌入式SQL的概念、构建方法以及在VC++环境下的具体应用。 嵌入式SQL...

    SQL 语句大全 SQL 语句大全

    学习并熟练掌握这些SQL语句将使你能够高效地操作和管理数据库,无论是在开发、数据分析还是数据库管理领域,SQL都是不可或缺的基础技能。通过"SQL 语句大全"文档,你可以深入理解并实践这些知识点,提升自己的数据库...

    泛微系统SQL语句大全

    综上所述,"泛微系统SQL语句大全"是一份宝贵的资源,它包含了构建、管理和优化泛微系统所需的各种SQL技巧和实例。无论你是系统管理员、开发人员还是数据分析者,都能从中受益,提升你在泛微系统中的工作效率和数据...

    SQL语句之Select语句技巧总结

    自己总结的一些关于SQL语句中Select语句常用的几种方法。里面有相信的说明,下载后查阅!

    vc++SQL语句嵌套

    SQL(Structured Query Language,结构化查询语言)是用于管理关系数据库的标准语言,而嵌套SQL语句则是指在一个SQL语句内部嵌入另一个或多个SQL语句。在VC++(Visual C++)开发环境中,我们经常需要与数据库进行...

    sql语句转string

    在IT行业中,数据库操作是核心...这个过程涉及到数据库的连接、SQL语句的构造以及结果的处理,需要熟悉JDBC API和相关的Java编程技巧。通过合理的方法和工具,我们可以有效地实现SQL与Java代码的融合,提高开发效率。

    根据word文档生成SQL语句(SQLServer) 及 实体类

    总之,通过Word文档生成SQL语句和实体类是一种实用的开发技巧,尤其适用于数据库设计复杂且需要快速原型化的项目。结合自动化工具,可以将繁琐的手动工作自动化,使开发人员能够更专注于业务逻辑和应用程序的核心...

    Effective MySQL之SQL语句最优化(高清)

    《Effective MySQL之SQL语句最优化》提供了很多可以用于改进数据库和应用程序性能的最佳实践技巧,并对这些技巧做了详细的解释。《Effective MySQL之SQL语句最优化》希望能够通过一步步详细介绍SQL优化的方法,帮助...

    .net core实用技巧——将EF Core生成的SQL语句显示在控制台中.docx

    .NET Core 实用技巧——将 EF Core 生成的 SQL 语句显示在控制台中 在本文中,我们将探讨如何将 EF Core 生成的 SQL 语句显示在控制台中,以便更好地理解和学习 .NET Core。 首先,我们需要了解 EF Core 生成的 ...

Global site tag (gtag.js) - Google Analytics