`
baoqf
  • 浏览: 109794 次
  • 来自: 杭州
社区版块
存档分类
最新评论

数据库查询优化原则,欢迎指正补充

阅读更多

    1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。

    2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:
    select id from t where num is null
    可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:
    select id from t where num=0

    3.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。

    4.应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如:
    select id from t where num=10 or num=20
    可以这样查询:
    select id from t where num=10
    union all
    select id from t where num=20

    5.in 和 not in 也要慎用,否则会导致全表扫描,如:
    select id from t where num in(1,2,3)
    对于连续的数值,能用 between 就不要用 in 了:
    select id from t where num between 1 and 3

    6.下面的查询也将导致全表扫描:
    select id from t where name like '%abc%'
    若要提高效率,可以考虑全文检索。

    7.如果在 where 子句中使用参数,也会导致全表扫描。因为SQL只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时;它必须在编译时进行选择。然而,如果在编译时建立访问计划,变量的值还是未知的,因而无法作为索引选择的输入项。如下面语句将进行全表扫描:
    select id from t where num=@num
    可以改为强制查询使用索引:
    select id from t with(index(索引名)) where num=@num

    8.应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如:
    select id from t where num/2=100
    应改为:
    select id from t where num=100*2

    9.应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。如:
    select id from t where substring(name,1,3)='abc'--name以abc开头的id
    select id from t where datediff(day,createdate,'2005-11-30')=0--‘2005-11-30’生成的id
    应改为:
    select id from t where name like 'abc%'
    select id from t where createdate>='2005-11-30' and createdate<'2005-12-1'

    10.不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。

    11.在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致。

    12.不要写一些没有意义的查询,如需要生成一个空表结构:
    select col1,col2 into #t from t where 1=0
    这类代码不会返回任何结果集,但是会消耗系统资源的,应改成这样:
    create table #t(...)

    13.很多时候用 exists 代替 in 是一个好的选择:
    select num from a where num in(select num from b)
    用下面的语句替换:
    select num from a where exists(select 1 from b where num=a.num)

    14.并不是所有索引对查询都有效,SQL是根据表中数据来进行查询优化的,当索引列有大量数据重复时,SQL查询可能不会去利用索引,如一表中有字段sex,male、female几乎各一半,那么即使在sex上建了索引也对查询效率起不了作用。
 15.索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有必要。

    16.应尽可能的避免更新 clustered 索引数据列,因为 clustered 索引数据列的顺序就是表记录的物理存储顺序,一旦该列值改变将导致整个表记录的顺序的调整,会耗费相当大的资源。若应用系统需要频繁更新 clustered 索引数据列,那么需要考虑是否应将该索引建为 clustered 索引。

    17.尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。

    18.尽可能的使用 varchar/nvarchar 代替 char/nchar ,因为首先变长字段存储空间小,可以节省存储空间,其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。

    19.任何地方都不要使用 select * from t ,用具体的字段列表代替“*”,不要返回用不到的任何字段。

    20.尽量使用表变量来代替临时表。如果表变量包含大量数据,请注意索引非常有限(只有主键索引)。

    21.避免频繁创建和删除临时表,以减少系统表资源的消耗。

    22.临时表并不是不可使用,适当地使用它们可以使某些例程更有效,例如,当需要重复引用大型表或常用表中的某个数据集时。但是,对于一次性事件,最好使用导出表。

    23.在新建临时表时,如果一次性插入数据量很大,那么可以使用 select into 代替 create table,避免造成大量 log ,以提高速度;如果数据量不大,为了缓和系统表的资源,应先create table,然后insert。

    24.如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除,先 truncate table ,然后 drop table ,这样可以避免系统表的较长时间锁定。

    25.尽量避免使用游标,因为游标的效率较差,如果游标操作的数据超过1万行,那么就应该考虑改写。

    26.使用基于游标的方法或临时表方法之前,应先寻找基于集的解决方案来解决问题,基于集的方法通常更有效。

    27.与临时表一样,游标并不是不可使用。对小型数据集使用 FAST_FORWARD 游标通常要优于其他逐行处理方法,尤其是在必须引用几个表才能获得所需的数据时。在结果集中包括“合计”的例程通常要比使用游标执行的速度快。如果开发时间允许,基于游标的方法和基于集的方法都可以尝试一下,看哪一种方法的效果更好。

    28.在所有的存储过程和触发器的开始处设置 SET NOCOUNT ON ,在结束时设置 SET NOCOUNT OFF 。无需在执行存储过程和触发器的每个语句后向客户端发送 DONE_IN_PROC 消息。

    29.尽量避免大事务操作,提高系统并发能力。

    30.尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理。

    具体的SQL语句在很多情况下需要结合实际的应用情况来写,这里不作叙述。

分享到:
评论

相关推荐

    mysql 单机数据库优化的一些实践

    本文试图描述单机数据库优化的一些实践,数据库基于mysql,如有不合理的地方,欢迎指正。 1、表结构优化 在开始做一个应用的时候,数据库的表结构设计往往会影响应用后期的性能,特别是用户量上来了以后的性能。...

    数据库发展研究报告(2023年)

    本报告是中 国通信标准化协会大数 据技术标准推进委员会 (CCSA TC601)继《数据库发展研究报告(2021 年)》、《数据库发展研究...由于水平所 限,错误和不足之处在所难免,欢迎各位读者批评指正,本报告为 内容简版,

    数据库思维导图 xmind

    简单总结一下数据库基础知识,如果有错误和缺少的或者不足的欢迎指正!!

    一个自己建立的bbs论坛数据库

    这涉及到了关系型数据库管理系统的知识,如MySQL、PostgreSQL等,以及SQL语言用于查询和操作数据。 【压缩包子文件的文件名称列表】:BBSDataBase “BBSDataBase”很可能是包含所有论坛数据的数据库文件,可能是一...

    关于数据库系统实现的实例

    限于译者水平,译文中疏漏和错误难免,欢迎批评指正。译者 2000年10月于北京大学 前 言本书是为斯坦福大学数据库系列课程的第二门课CS245设计的。第一门课程CS145的内容包括数据库设计和数据库编程,Jeff Ullman...

    Oracle8i_9i数据库基础

    尽管Oracle的产品和技术不断发展,但这份教材依然具有很高的参考价值,尽管可能存在一些错误或不足,作者也诚挚欢迎读者的反馈和指正。 总的来说,Oracle8i/9i数据库基础是一份全面且实用的Oracle学习资源,它不仅...

    oracle数据库数据同步

    开发背景: 为了满足客户的要求,客户要求两台数据库服务器在不能直接通信的情况下,要保证两台数据库数据保持同步,并且要保证效率,数据量...希望对刚好有这需求的人有帮助,同时也欢迎指正程序中的不足,共同进步。

    Oracle8i9i高级数据库管理.doc

    本部分将详细介绍SQL查询优化、索引策略、表分区、存储优化和数据库参数调整等技巧,帮助读者提升数据库的运行效率,减少资源消耗。 书中还涵盖了Oracle8i OCP(Oracle Certified Professional)认证考试的最新培训...

    数据库系统实现(斯坦福大学教材)

    限于译者水平,译文中疏漏和错误难免,欢迎批评指正。译者 2000年10月于北京大学 前 言本书是为斯坦福大学数据库系列课程的第二门课CS245设计的。第一门课程CS145的内容包括数据库设计和数据库编程,Jeff Ullman...

    oracle数据库从入门到精通

    此外,书中还详细介绍了TMS系统的功能菜单、页签、查询条件、查询列表以及查询按钮等模块的配置方法。配置TMS系统是一个系统化的过程,需要按照一定的步骤和流程来进行。 对于初学者来说,本书提供的内容结构合理、...

    .net数据库操作框架附源码

    使用方法: 修改app.config中的数据库连接字符串,默认SQLSERVER,其他数据库需要加一个 providerName。 将app.config放入项目内。....net数据库操作框架附源码,也许有写的不完美的地方,欢迎指正!

    精通Delphi数据库设计与实例开发配套光盘

    本书系统而全面地讲解了使用Delpt"1i开发数据库应用程序的方法,包括Delphi的快速入门、Object PascaI的语法基础、基本组件的使用方法、数据库基础知识、数据库环境设置、连接数据库的方法、使用BDE和ADO等组件进行...

    DatabaseImageViewer 数据库二进制数据查看器

    DatabaseImageViewer 数据库二进制数据查看器 ...功能很简单,欢迎大家使用指正,软件可能还有不完善的地方,如果有时间我会进行更新修正! git源码地址:https://github.com/kehehee1/DatabaseImageViewer

    数据库与软件工程 思维导图.xmind

    我整理了《数据库系统原理与设计》一书和《软件工程:...很适合初学者学习以及回顾知识的过程,花费了很久,但也收获了许多,独乐乐不如众乐乐,先将这个分享出来,内容可能有个别错误,欢迎大家指正,QQ:1666286142

    java 图书管理系统(Java源码 + Mysql数据库).rar

    【实例简介】图书管理系统 Java MySQL 完整实训代码,MVC三层架构组织,包含所有用到的...项目文档包括8000字的实训报告,从系统需求分析,系统设计,系统实现思路,系统具体实现都做了详细的分析,欢迎大家批评指正。

    ORACLE8i/9i数据库管理基础

    除了DBA所需技能,本书还包含了系统分析员所需的知识,如数据库设计原则、安全性管理以及数据库的高可用性解决方案。这些内容对于那些参与系统分析与设计的人员来说非常有用,可以帮助他们更好地理解和规划ORACLE...

    数据库发展研究报告.pdf

    本报告重点阐述了数据库作为信息系统的核心,它是管理和分析数据的关键技术,为社会进步提供了重要推动力。自计算机发明以来,信息处理已从传统工具转向电子化编码的数据处理。数据库系统作为承载数据存储和计算功能...

    全球地区数据库(全面).xlsx

    详细的全球地区数据库,240个国家共7293行数据,中国细化到省市地区县(数据来源于国家统计局2014年发布的数据),其他国家细化到二级行政区(数据来源于QQ注册页面),99%的数据都带经纬度信息,泣血整理,如有错误...

Global site tag (gtag.js) - Google Analytics