我们做开发的人员,虽说自己不是专业从事数据库方面研究的(如DBA),但很多时候,公司没有专门的DBA,所以拿到具体的项目中,整体的数据库设计都是开发人员自己写的,随着时间的推移,加上开发经验的增长,越来越关心如何设计好的数据库,如何写出高效的sql语句。之所以非常关心数据库及sql语句的写法,主要是在程序逻辑代码上大家都有可能写出一样的效率的功能方法来,而sql语句呢,对于同样的结果集,一个初级的开发人员与一个资深的开发人员或者DBA写出的sql语句执行效率有着很大的差距。这里对数据库设计略过,主要说说正确建立索引,带来的性能提高。(还好,我们公司有DBA,自己写好的sql语句可以让他帮忙看看)

看sql 的性能,主要看执行计划,还有cpu成本,io成本等。这里就以一个简的表为例。

首先,创建一个简单的表,一般会先建个主键,系统自动以主键建聚集索引。语句如下:

Code  1CREATE TABLE [dbo].[Article](  2    [Id] [int] IDENTITY(1,1) NOT FOR REPLICATION NOT NULL,  3    [MsId] [int] NOT NULL,  4    [Title] [nvarchar](96) NOT NULL,  5    [TitleBak] [nvarchar](96) NOT NULL,  6    [Summary] [nvarchar](512) NOT NULL,  7    [SummaryImageUrl] [nvarchar](256) NOT NULL,  8    [Tag] [nvarchar](50) NOT NULL,  9    [ArticleChannel_Id] [int] NOT NULL, 10    [ArticleCategory_Id] [int] NOT NULL, 11    [IsApproved] [bit] NOT NULL, 12    [Creator_Id] [int] NOT NULL, 13    [CreatedDateTime] [datetime] NOT NULL, 14    [ModifiedDateTime] [datetime] NOT NULL, 15    [ViewCount] [int] NOT NULL, 16    [ReplyCount] [int] NOT NULL, 17    [DiggCount] [int] NOT NULL, 18    [FavoriteCount] [int] NOT NULL, 19    [LastReplyUser_Id] [int] NOT NULL, 20    [LastReplyDateTime] [datetime] NOT NULL, 21    [RightType] [int] NOT NULL, 22    [IsDisplayContent] [bit] NOT NULL, 23    [IsSensitive] [bit] NOT NULL, 24    [Source] [int] NOT NULL, 25 CONSTRAINT [PK_Articles] PRIMARY KEY CLUSTERED  26( 27    [Id] ASC 28)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY] 29) ON [PRIMARY] 30

填充200000测试数据,

Code  1DECLARE @number INT  2SET @number = 200000  3  4WHILE @number > 0  5BEGIN  6    INSERT dbo.Article  7      (  8        MsId,  9        Title, 10        TitleBak, 11        Summary, 12        SummaryImageUrl, 13         14        Tag, 15        ArticleChannel_Id, 16        ArticleCategory_Id, 17        IsApproved, 18        Creator_Id, 19         20        CreatedDateTime, 21        ModifiedDateTime, 22        ViewCount, 23        ReplyCount, 24        DiggCount, 25         26        FavoriteCount, 27        LastReplyUser_Id, 28        LastReplyDateTime, 29        RightType, 30        IsDisplayContent, 31         32        IsSensitive, 33        Source 34      ) 35    VALUES 36      ( 37          @number, 38        'Title'+cast(@number AS VARCHAR(20)), 39        'TitleBak'+cast(@number AS VARCHAR(20)), 40        'Summary'+cast(@number AS VARCHAR(20)), 41        'SummaryImageUrl'+cast(@number AS VARCHAR(20)), 42         43        'Tag'+cast(@number AS VARCHAR(20)), 44        1, 45        2, 46        0, 47        @number, 48         49        GETDATE(), 50       GETDATE(), 51        100, 52        29, 53        123, 54         55        12, 56        @number, 57        GETDATE(), 58        1, 59        0, 60         61        0, 62        2 63           64      ) 65      SET @number=@number-1 66END 67

创建索引,什么时候创建,为哪个字段创建等等一系列的问题在这里统统的撂下,在这里进行一步步的带有试探的创建非聚集索引,看看建立索引前后以及不同的索引会有什么样的不同。

先说明一下,通过执行计划,判断是否需要优化sql的一个简单规则是:看执行计划中的操作是seek(搜索)还是scan(扫描)

长话短说,马上开始,

 
WITH TEMP AS ( SELECT ROW_NUMBER() OVER (ORDER BY CreatedDateTime) AS ROW,CreatedDateTime,ViewCount FROM Article WHERE Creator_Id=199996  ) SELECT * FROM TEMP WHERE ROW BETWEEN 1 AND 5
 

通过执行计划,看到是操作是聚集索引扫描。我们刚才说了,seek操作性能更好一些,那如何优化这条语句呢,对Creator_Id建非聚集索引。

创建Ix_article_creatorid 索引,

CREATE INDEX Ix_article_creatorid ON Article(Creator_Id)

再看下执行计划,

哦,加了Ix_article_creatorid索引后,聚集索引扫描操作改为索引查找和聚集索引查找,对于我们开发人员来说,一般的认为可以了。如果所开发的系统在正常运行一段时间后,需要优化,可以对此语句继续进行优化。

看完执行计划,想到了应该再看看cpu占用时间,IO资源等情况,主要用到命令

set statistics io 和 set statistics,这是性能调优时查看相关cpu占用时间,IO资源数据的两个比较重要的命令。

今天就先到了,下篇再介绍这两个命令吧。

备注:

其实没有详细介绍如何创建高效性能的索引,主要原因是根据不同的环境对待系统的要求不同,而优化也有所不同,当一个系统查询比较频繁,而新建,修改等操作比较少时,可以创建覆盖索引,将查询字段和where子句里的字段全部包含在内,这样查询的速度会比以前快很多,同时也带来弊端,就是新建或修改等操作时,比没有索引或没有建立覆盖索引时的要慢。总结一句话就是,具体问题具体分析。

数据库里的知识也是博大精深,并不是当初认为会写几条sq         l语句就以为非常精通了数据库什么的,真正要写出好的语句,得下功夫,了解数据库的底层,再经常问问DB牛人,慢慢积累后,也许你也能成为DB牛人呢。总结一句话就是,只要功夫深,铁杵磨成针。

如何创建效率高sql-建立索引的更多相关文章

  1. sql 建立索引之前计算区分度

    select cutomer_id,title,content from product_comment where audit_status=1 and product_id=1 and produ ...

  2. 高性能mysql 第5章 创建高可用的索引

    b-tree索引 一定程度上说,mysql只有b-tree索引.他没有bitmap索引.还有一个叫hash索引的,只在Memory存储引擎中才有. b-tree索引跟oracle中的大同小异. mys ...

  3. SQL 数据优化之不建立索引的情况

    索引可以提高数据的检索效率,也可以降低数据库的IO成本,并且索引还可以降低数据库的排序成本.排序分组操作主要消耗的就是CPU资源和内存,所以能够在排序分组操作中好好的利用索引将会极大地降低CPU资源的 ...

  4. Oracle 建立索引及SQL优化

    数据库索引: 索引有单列索引,复合索引之说,如果某表的某个字段有主键约束和唯一性约束,则Oracle 则会自动在相应的约束列上建议唯一索引.数据库索引主要进行提高访问速度. 建设原则: 1.索引应该经 ...

  5. SQL Server 2008中如何为XML字段建立索引

    from:http://blog.csdn.net/tjvictor/article/details/4370771 SQL Server中的XML索引分为两类:主XML 索引和辅助XML索引.其中辅 ...

  6. SQL Server 索引的创建原则

    避免对经常更新的表进行过多的索引,并且索引中的列尽可能少.而对经常用于查询的字段(外键)应该创建索引,但要避免添加不必要的字段. 数据量小的表最好不要使用索引,由于数据较少,查询花费的时间可能比遍历索 ...

  7. 为什么存储过程比sql语句效率高?

    存储过程经过预编译处理 而SQL查询没有 SQL语句需要先被数据库引擎处理成低级的指令 然后才执行 -------------------------------------------------- ...

  8. 存储过程为什么比sql效率高

    对于存储过程为什么比sql效率高的原因有4点 第一就是使用存储过程允许组建式编成, 二是可以对程序进行编译,

  9. SQL Server索引进阶:第十二级,创建,修改,删除

    在第十级中我们看到了索引的内部结构,在第十一级中我们看到了平衡树结构潜在的负面影响:索引碎片.有了索引内部结构的知识,我们可以检查在执行数据定义语句和数据操作语句的时候,都发生了什么.在本级中我们介绍 ...

随机推荐

  1. 2015-02-09——js笔记

    示例1: 增加样式表 示例代码: function addStylesheet(url, media) {                var link = document.createEleme ...

  2. Android系统移植与调试之------->如何修改Android手机NFC模块,使黑屏时候能够使用NFC

    我们都知道在不修改源代码的情况下,只能是解锁之后才能使用NFC功能.而在锁屏和黑屏2个状态下是没办法用NFC的,但是最近有个客户要求手机在黑屏状态下能够使用NFC,因此我们需要去修改Android源代 ...

  3. C++学习之旅get、getline的使用方法

    C++学习之旅get.getline的使用方法 面向行的输入:cin.getline(). 该函数读取整行.它使用通过回车键输入的换行符来确定输入结尾.要调用这样的方法,能够使用cin.getline ...

  4. Python基础(19)_异常处理

    一.异常处理 错误和异常: 1.错误的种类: 1)语法错误:这种错误,根本过不了python解释器的语法检测,必须在程序执行前就改正 2)逻辑错误: 例如: res1=1/0  .es2=1+'str ...

  5. CSS 中z-index全解析(摘自阿里西西)

    z-index全解析 Z-index属性决定了一个HTML元素的层叠级别.元素层叠级别是相对于元素在Z轴上(与X轴Y轴相对照)的位置而言.一个更高的Z-index值意味着这个元素在叠层顺序中会更靠近顶 ...

  6. BIO,NIO和AIO

    BIO:同步阻塞式IO,服务器实现模式为一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理,如果这个连接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制改善. NIO: ...

  7. qq 微信 微博 第三方分享

    <html> <head> <meta charset="utf-8"> <meta name="viewport" ...

  8. ios-如何搭建IPv6网络测试环境(转)

    工具/原料   mac一台 iPhone手机2台(一台用于测试,另一台提供网络) 方法/步骤     准备网络.通过数据线连接iPhone和Mac,并将iPhone手机连接的Wi-Fi关闭,使用自己的 ...

  9. android 7.0 (nougat)的编译优化-ninja

    http://blog.csdn.net/songjam/article/details/52640501 版权声明:本文为博主原创文章,未经博主允许不得转载. 从官方的定义,ninja大大缩短了an ...

  10. $.queue() 与 $.dequeue() -- 队列

    JQuery 运用队列为动画模块服务,但好像它应该有更多用处,我觉得的,那试试就知道咯. 简单的来讲,它就是形成队列和出列, 也就因此可以进行很有规律的回调和延时了呀(暂停感觉有难度),当然这就是后面 ...