`
Zhijie.Geng
  • 浏览: 54903 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

如何让你的SQL运行得更快,SQL优化

阅读更多
本文转载:
http://blog.csdn.net/gprime/article/details/1687930

在使用 SQL 往往会陷入一个 区,即太 注于所得的 果是否正确,而忽略了不同的 实现 方法之 可能存在的性能差异, 这种 性能差异在大型的或是 复杂 的数据 库环 境中(如 机事 务处 OLTP 或决策支持系 DSS )中表 得尤
笔者在工作 践中 发现 ,不良的 SQL 往往来自于不恰当的索引 设计 、不充份的 接条件和不可 化的 where 子句。
们进 行适当的 化后,其运行速度有了明 地提高!
下面我将从 三个方面分 别进 总结
了更直 问题 ,所有 例中的 SQL 运行 时间 经过测试 ,不超 1秒的均表示 < 1 秒)。 ----
测试环 : 主机: HP LH II---- 330MHZ---- 内存: 128 ----
操作系 Operserver5.0.4----
数据 Sybase11.0.3
 
一、不合理的索引 设计 ----
例:表 record 620000 行, 看在不同的索引下,下面几个 SQL 的运行情况:
---- 1. date 上建有一非个群集索引
select count(*) from record where date >'19991201' and date < '19991214'and amount >2000 (25 )
select date ,sum(amount) from record group by date(55 )
select count(*) from record where date >'19990901' and place in ('BJ','SH') (27 )
---- 分析: ----
date 上有大量的重 复值 ,在非群集索引下,数据在物理上随机存放在数据 上,在范 围查 ,必 须执 行一次表 描才能找到 一范 内的全部行。
---- 2. date 上的一个群集索引
select count(*) from record where date >'19991201' and date < '19991214' and amount >2000 14 秒)
select date,sum(amount) from record group by date 28 秒)
select count(*) from record where date >'19990901' and place in ('BJ','SH') 14 秒)
---- 分析: ---- 在群集索引下,数据在物理上按 序在数据 上,重 复值 也排列在一起,因而在范 围查 ,可以先找到 个范 的起末点,且只在 个范 描数据 ,避免了大范 围扫 描,提高了 查询 速度。
---- 3. place date amount 上的 合索引
select count(*) from record where date >'19991201' and date < '19991214' and amount >2000 26 秒)
select date,sum(amount) from record group by date 27 秒)
select count(*) from record where date >'19990901' and place in ('BJ, 'SH') < 1 秒)
---- 分析: ---- 是一个不很合理的 合索引,因 它的前 列是 place ,第一和第二条 SQL 没有引用 place ,因此也没有利用上索引;第三个 SQL 使用了 place ,且引用的所有列都包含在 合索引中,形成了索引覆盖,所以它的速度是非常快的。
---- 4. date place amount 上的 合索引
select count(*) from record where date >'19991201' and date < '19991214' and amount >2000(< 1 )
select date,sum(amount) from record group by date 11 秒)
select count(*) from record where date >'19990901' and place in ('BJ','SH') < 1 秒)
---- 分析: ---- 是一个合理的 合索引。它将 date 列,使 SQL 都可以利用索引,并且在第一和第三个 SQL 中形成了索引覆盖,因而性能达到了最
---- 5. 总结 ----
缺省情况下建立的索引是非群集索引,但有 它并不是最佳的;合理的索引 设计 要建立在 种查询 的分析和 预测 上。
一般来
. 有大量重 复值 、且 常有范 围查询 between, >,< >=,< = )和 order by group by 生的列,可考 建立群集索引;
. 常同 存取多列,且 列都含有重 复值 可考 建立 合索引;
. 合索引要尽量使 关键查询 形成索引覆盖,其前 列一定是使用最 繁的列。
 
二、不充份的 接条件:
例:表 card 7896 行,在 card_no 上有一个非聚集索引,表 account 191122 行,在 account_no 上有一个非聚集索引, 看在不同的表 接条件下,两个 SQL 行情况:
select sum(a.amount) from account a,card b where a.card_no = b.card_no 20 秒)
select sum(a.amount) from account a,card b where a.card_no = b.card_no and a.account_no=b.account_no < 1 秒)
---- 分析: ---- 在第一个 接条件下,最佳 查询 方案是将 account 作外 表, card 作内 表,利用 card 上的索引,其 I/O 次数可由以下公式估算
account 上的 22541 + (外 account 191122 * card 对应 表第一行所要 找的 3 =595907 I/O
在第二个 接条件下,最佳 查询 方案是将 card 作外 表, account 作内 表,利用 account 上的索引,其 I/O 次数可由以下公式估算 :外 card 上的 1944 + (外 card 7896 * account 对应 一行所要 找的 4 = 33528 I/O
,只有充份的 接条件,真正的最佳方案才会被 行。
总结
1. 多表操作在被 实际执 行前, 查询优 化器会根据 接条件,列出几 可能的 接方案并从中找出系 统开销 最小的最佳方案。 接条件要充份考 虑带 有索引的表、行数多的表;内外表的 选择 可由公式:外 表中的匹配行数 * 表中 一次 找的次数确定,乘 最小 最佳方案。
2. 行方案的方法 -- set showplan on ,打 showplan 选项 ,就可以看到 序、使用何 索引的信息;想看更 详细 的信息,需用 sa 角色 dbcc(3604,310,302)
 
三、不可 化的 where 子句
1. 例:下列 SQL 条件 句中的列都建有恰当的索引,但 行速度却非常慢:
select * from record where substring(card_no,1,4)='5378'(13 )
select * from record where amount/30< 1000 11 秒)
select * from record where convert(char(10),date,112)='19991201' 10 秒)
分析:
where 子句中 列的任何操作 果都是在 SQL 运行 逐列 算得到的,因此它不得不 行表搜索,而没有使用 列上面的索引;
如果 果在 查询编译时 就能得到,那 就可以被 SQL 化器 化,使用索引,避免表搜索,因此将 SQL 重写成下面 这样
select * from record where card_no like'5378%' < 1 秒)
select * from record where amount< 1000*30 < 1 秒)
select * from record where date= '1999/12/01' < 1 秒)
你会 发现 SQL 快起来!
2. 例:表 stuff 200000 行, id_no 上有非群集索引, 看下面 SQL
select count(*) from stuff where id_no in('0','1') 23 秒)
分析: ---- where 条件中的 'in' 逻辑 上相当于 'or' ,所以 法分析器会将 in ('0','1') id_no ='0' or id_no='1' 行。
期望它会根据 or 子句分 别查 找,再将 果相加, 这样 可以利用 id_no 上的索引;
实际 上(根据 showplan , 它却采用了 "OR 策略 " ,即先取出 or 子句的行,存入 临时 数据 的工作表中,再建立唯一索引以去掉重 行,最后从 临时 表中 果。因此, 实际过 程没有利用 id_no 上索引,并且完成 时间还 要受 tempdb 数据 性能的影响。
明,表的行数越多,工作表的性能就越差,当 stuff 620000 时间 竟达到 220 秒! 不如将 or 子句分
select count(*) from stuff where id_no='0'select count(*) from stuff where id_no='1'
得到两个 果,再作一次加法合算。因 为每 句都使用了索引, 时间 只有 3 秒,在 620000 行下, 时间 也只有 4 秒。
或者,用更好的方法,写一个 简单 的存 储过 程:
create proc count_stuff asdeclare @a intdeclare @b intdeclare @c intdeclare @d char(10)beginselect @a=count(*) from stuff where id_no='0'select @b=count(*) from stuff where id_no='1'endselect @c=@a+@bselect @d=convert(char(10),@c)print @d
直接算出 果, 时间 同上面一 快!
 
---- 总结 ---- ,所 谓优 化即 where 子句利用了索引,不可 化即 生了表 描或 开销
1. 任何 列的操作都将 致表 描,它包括数据 函数、 算表达式等等, 查询时 要尽可能将操作移至等号右
2.in or 子句常会使用工作表,使索引失效;如果不 生大量重 复值 ,可以考 把子句拆 ;拆 的子句中 应该 包含索引。
3. 要善于使用存 储过 程,它使 SQL 得更加灵活和高效。
从以上 些例子可以看出, SQL 化的 实质 就是在 果正确的前提下,用 化器可以 识别 句,充份利用索引,减少表 描的 I/O 次数,尽量避免表搜索的 生。其 SQL 的性能 化是一个 复杂 程,上述 些只是在 次的一 ,深入研究 及数据 库层 源配置、网 络层 的流量控制以及操作系 统层 设计
分享到:
评论

相关推荐

    如何让你的SQL运行得更快

    如何让你的SQL运行得更快,优化你的SQL。 全面介绍SQL的编写

    数据库优化之让你的SQL运行得更快

    SQL优化的实质就是在结果正确的前提下,用优化器可以识别的语句,充份利用索引,减少表扫描的I/O次数,尽量避免表搜索的发生。其实SQL的性能优化是一个复杂的过程,这些只是在应用层次的一种体现,深入研究还会涉及...

    如何让你的SQL运行更快

    主要讲解怎样优化SQL程序!让你的SQL运行更快

    案例学习:如何让你的SQL运行得更快

    案例学习:如何让你的SQL运行得更快

    LECCO SQL Expert (智能自动SQL优化)

    更优更快 人工智能自动SQL优化----------http://www.sina.com.cn 2001/12/12 17:48 中国电脑教育报文/SQL爱好者 所谓SQL,就是指Structured Query Language(结构化查询语言),它是目前使用最广泛的数据库语言,用来...

    Oracle sql 性能优化调整

    Oracle sql 性能优化调整,让你的sql运行更快

    SQL 优化原则

     在多数情况下,Oracle使用索引来更快地遍历表,优化器主要根据定义的索引来提高性能。但是,如果在SQL语句的where子句中写的SQL代码不合理,就会造成优化器删去索引而使用全表扫描,一般就这种SQL语句就是所谓的...

    SQL Server数据库查询速度慢原因及优化方法

    运行 Microsoft SQL Server? 2000时,可考虑将虚拟内存大小设置为计算机中安装的物理内存的1.5倍。如果另外安装了全文检索功能,并打算运行Microsoft搜索服务以便执行全文索引和查询,可考虑:将虚拟内存大小配置为...

    SQL查询安全性及性能优化

    SQL优化 为什么要优化 开发是对性能考虑不多【技术差、项目工期紧等原因没有考虑性能问题】 系统运行中,数据量扩大,访问量增多,蹩脚的SQL危害开始显露 低效SQL的危害 系统响应变慢,软件开发中的8秒定律,当...

    SQLServer2008查询性能优化 2/2

    《SQL Server 2008查询性能优化》不是理论书籍,它的目的是帮助你避免数据库出现性能低下的状况,它还能帮助你保住你的工作。 内容提要 《SQL Server 2008查询性能优化》通过大量实例,详细介绍了SQL Server数据库...

    SQL性能优化

    9. 让 SQL 语句用上合理的索引,合理让 SQL 语句使用索引的原则如下:  首先,看是否用上了索引,对于该使用索引而没有用上索引的 SQL 语句,应该想办法用上索引。  其次,看是否用上正确的索引了,特别复杂的 ...

    SQLServer安全及性能优化

    我们可以在运行引擎优化顾问前运用sqlserver profiler记录一些事件,然后将跟踪结果存储为文件或者数据表,然后把这些提供给数据库引擎优化顾问,让它去分析。  提出合理的物理设计结构,物理设计结构包括数据库中...

    [转载]让SQL运行得更快

    笔者在工作实践中发现,不良的SQL往往来自于不恰当的索引设计、不充份的连接条件和不可优化的where子句。在对它们进行适当的优化后,其运行速度有了明显地提高!下面我将从这三个方面分别进行总结

    SQLServer2008查询性能优化 1/2

    《SQL Server 2008查询性能优化》不是理论书籍,它的目的是帮助你避免数据库出现性能低下的状况,它还能帮助你保住你的工作。 内容提要 《SQL Server 2008查询性能优化》通过大量实例,详细介绍了SQL Server数据库...

    查询的优化,让程序运行的更快,让服务器负载更小!

    让程序运行的更快,让服务器负载更小!好东西

    Microsoft SQL Server 2008技术内幕:T-SQL查询(第二卷)

    《Microsoft SQL Server 2008技术内幕:T-SQL查询》全面深入地介绍了Microsoft SQL Server 2008中高级T-SQL查询、性能优化等方面的内容,以及SQL Server 2008新增加的一些特性。主要内容包括SQL的基础理论、查询优化...

    五种提高 SQL 性能的方法总结

    五种提高 SQL 性能的方法 超好!!有时, 为了让应用程序运行得更快,所做的全部工作就是在这里或那里做一些很小调整。。。。。

    SQL21日自学通

    让你的SQL 语句更易读307 全表扫描308 加入一个新的索引309 在查询中各个元素的布局309 过程311 避免使用OR311 OLAP 与OLTP 的比较313 OLTP 的调试313 OLAP 的调试314 批量载入与事务处理进程314 删除索引以优化数据...

    PL/SQL Developer

     性能优化——使用PL/SQL Profiler,可以浏览每一执行的PL/SQL代码行的时序信息(Oracle8i或更高),从而优化您SQL和PL/SQL的代码性能。  更进一步,您还可以自动获取所执行的SQL语句和PL/SQL程序统计信息。该...

Global site tag (gtag.js) - Google Analytics