应用索引技术优化SQL 语句三

六、有关索引的几个问题

问题1,是否值得在identity字段上建立聚集索引。答案取决于identity 字段如何在语句中使用。如果你经常根据该字段搜索返回很少的行,那么在其上建立索引是值得的。反之如果identity字段根本很少在语句中使用,那么就不应该对其建立任何索引。

问题2,一个表应该建立多少索引合适。如果表的80%以上的语句都是读操作,那么索引可以多些。但是不要太多。特别是不要对那些更新频繁的表其建立很多的索引。很少表有超过5个以上的索引。过多的索引不但增加其占用的磁盘空间,也增加了SQL Server 维护索引的开销。

问题4:为什么SQL Server 在执行计划中没有使用你认为应该使用的索引?原因是多样的。一种原因是该语句返回的结果超过了表的20%数据,使得SQL Server 认为scan比seek更有效。

另一种原因可能是表字段的statistics过期了,不能准确反映数据的分布情况。你可以使用命令UPDATE STATISTICS tablename with FULLSCAN来更新它。只有同步的准确的statistics才能保证SQL Server 产生正确的执行计划。过时的老的statistics常会导致SQL Server生成不够优化的甚至愚蠢的执行计划。所以如果你的表频繁更新,而你又觉得和之相关的SQL语句运行缓慢,不妨试试UPDATE STATISTIC with FULLSCAN 语句。

你甚至可以使用Index hint比较不同索引的性能差异。比如对上面script 4提到的两个索引,可以这样比较,

select 学生姓名, 入学时间 from tbl1 with (index= idx_年龄入学时间)

where  ……

或者:

select 学生姓名, 入学时间 from tbl1 with (index= idx_入学时间年龄)

where  ……

如果强制使用你的索引后logical reads大大减少,那么就需要进一步研究为什么SQL Server 不使用正确的索引。注意,不要总是将使用索引等同于好的性能,反之亦然。SQL Server只在索引能提高性能时才使用索引检索。有时候使用Table scan的性能比使用某个索引反而要好。

问题5、什么使用聚集索引,什么时候使用非聚集索引

在SQL Server 中索引有聚集索引和非聚集索引两种。它们的主要差别是前者的索引叶子就是数据本身,而后者的叶子节点包含的是指向数据的书签(即数据行号或聚集索引的key)。

在上面的例子中我全部使用非聚集索引,原因是对一个表而言聚集索引只能有一个,而非聚集索引可以有多个。如果你把上面例子中的非聚集索引换成聚集索引,效果也是类似的,只是聚集索引没有Bookmark Lookup操作。什么时候应该使用聚集索引,什么时候使用非聚集索引取决于应用程序的访问模式。我的建议是在那些关键的字段上使用聚集索引。一个表一般都需要建立一个聚集索引。对于什么时候使用聚集索引,SQL Server 2000联机手册中有如下描述:

在创建聚集索引之前,应先了解您的数据是如何被访问的。可考虑将聚集索引用于:

  • 包含大量非重复值的列。
  • 使用下列运算符返回一个范围值的查询:BETWEEN、>、>=、< 和 <=。
  • 被连续访问的列。
  • 返回大型结果集的查询。
  • 经常被使用联接或 GROUP BY 子句的查询访问的列;一般来说,这些是外键列。对 ORDER BY 或 GROUP BY 子句中指定的列进行索引,可以使 SQL Server 不必对数据进行排序,因为这些行已经排序。这样可以提高查询性能。
  • OLTP 类型的应用程序,这些程序要求进行非常快速的单行查找(一般通过主键)。应在主键上创建聚集索引。

 

聚集索引不适用于:

  • 频繁更改的列

这将导致整行移动(因为 SQL Server 必须按物理顺序保留行中的数据值)。这一点要特别注意,因为在大数据量事务处理系统中数据是易失的。

  • 宽键

来自聚集索引的键值由所有非聚集索引作为查找键使用,因此存储在每个非聚集索引的叶条目内。

七、结束语

如何使一个性能缓慢的系统运行更快更高效,不但需要整体分析数据库系统,找出系统的性能瓶颈,更需要优化数据库系统发出的SQL 语句。一旦找出关键的SQL 语句并加与优化,性能问题就会迎刃而解。读完本文,你应该知道创建索引的关键是什么,以及如何分析SQL语句的执行计划来创建索引。在优化了索引后大部分数据库系统的性能都能够得到不同程度的改善,有的系统甚至能够获得好几倍以上的性能提升。本文并不能解决你在优化SQL语句中碰到的所有问题,但其中讨论的内容或技巧对许多性能问题都有一定的参考意义。

时间: 2024-11-02 23:37:39

应用索引技术优化SQL 语句三的相关文章

应用索引技术优化SQL 语句一

一.前言 很多数据库系统性能不理想是因为系统没有经过整体优化,存在大量性能低下的SQL 语句.这类SQL语句性能不好的首要原因是缺乏高效的索引.没有索引除了导致语句本身运行速度慢外,更是导致大量的磁盘读写操作,使得整个系统性能都受之影响而变差.解决这类系统的首要办法是优化这些没有索引或索引不够好的SQL语句. 本文讨论和索引相关的有关内容,以及通过分析语句的执行计划来讲述如何应用索引技术来优化SQL 语句.通过分析执行计划,读者可以检查索引是否有用,以及如何创建高效的索引.本文对数据库管理人员以

应用索引技术优化SQL 语句二

四.分析执行计划创建索引   根据语句的执行计划来判断应该对什么表创建什么索引,是常用优化技巧.其实文章前面的例子已经告诉读者如何结合statistics profile 和statistics IO语句的输出来创建索引.这里分析一个稍微复杂一些的例子. SQL语句如下: SELECT CurrentseNo FROM v_ptdata_edss WHERE MRN = @P1 Statistics IO的输出如下: Table 'ptseoutpat'. Scan count 2, logic

【转】 如何优化sql语句

============推荐============ csdn:http://blog.csdn.net/e3002/article/details/1817941 ====如何优化sql语句==== (1)选择最有效率的表名顺序(只在基于规则的优化器中有效): ORACLE的解析器按照从右到左的顺序处理FROM子句中的表名,FROM子句中写 在最后的表(基础表 driving table)将被最先处理,在FROM子句中包含多个表的 情况下,你必须选择记录条数最少的表作为基础表.如果有3个以上的

点评阿里JAVA手册之MySQL数据库 (建表规约、索引规约、SQL语句、ORM映射)

下载原版阿里JAVA开发手册  [阿里巴巴Java开发手册v1.2.0] 本文主要是对照阿里开发手册,注释自己在工作中运用情况. 本文内容:MySQL数据库 (建表规约.索引规约.SQL语句.ORM映射) 本文难度系数为三星(★★★) 本文为第四篇 第一篇 点评阿里JAVA手册之编程规约(命名风格.常量定义.代码风格.控制语句.注释规约) 第二篇 点评阿里JAVA手册之编程规约(OOP 规约 .集合处理 .并发处理 .其他) 第三篇 点评阿里JAVA手册之异常日志(异常处理 日志规约 ) 第四篇

性能优化——SQL语句(续)

上篇博客介绍了一下自己在项目中遇到的一种使用sql语句的优化方式(性能优化--SQL语句),但是说的不够完整.在对比的过程中,没有将max函数考虑在内,经人提醒之后赶紧做了一个测试,测试过程中又学到了不少的东西.现给大家分享一下 上次用的是select count(*) 和select * 的执行效率问题,因为我的需求是获取数据的一个总数来自动给出新的id,然后网友给出可以使用max的方式给出新id.其实这也是一种不错的思路(当时我们也用过该函数,只不过因为系统数据本身问题,不适合用该函数),然

数据库调优教程(十二) 优化sql语句

五.           优化Sql语句 上一章讲了如何设计一张好的表,一张好的表自然需要好的sql语句去操作它.本章就来聊聊如何优化sql语句. 1.      Sql语句优化原则 优化需要优化的Query 定位优化对象性能瓶颈 从Explain入手 尽可能在索引中完成排序 只取自己需要的Column 尽可能避免复杂的join和子查询 2.     优化limit select * from test1 order by id limit 99999,10 原语句虽然使用了id索引,但是相当于

mysql优化sql语句

mysql优化sql语句 常见误区 www.2cto.com 误区1: count(1)和count(primary_key) 优于 count(*) 很多人为了统计记录条数,就使用 count(1) 和 count(primary_key) 而不是 count(*) ,他们认为这样性能更好, 其实这是一个误区.对于有些场景,这样做可能性能会更差,应为数据库对 count(*) 计数操作做了一些特别的优化. 误区2: count(column) 和 count(*) 是一样的 这个误区甚至在很多

通过profile优化SQL语句

开启profile优化SQL语句:set profiling=1;执行SQL语句show profiles;show profile for query 2;//根据query_id 查看某个查询的详细时间耗费 SHOW STATUS LIKE 'last_query_cost';//查询上一条语句执行的代价 例: mysql> show profiles;+----------+------------+----------------------------------------+| Qu

Mysql性能优化----SQL语句优化、索引优化、数据库结构优化、系统配置优化、服务器硬件优化

一.SQL语句优化 1-1.MySQL慢日志 1).慢日志开启方式和存储格式 如何发现有问题的SQL? 使用Mysql慢日志对有效率问题的SQL进行监控 前期准备 mysql> show variables like '%log_queri%'; +-------------------------------+-------+ | Variable_name | Value | +-------------------------------+-------+ | log_queries_no