Asp.Net网站优化系列之数据库的优化措施与索引优化方法

另外在sql server内存够用的情况下索引会被放到内存中,在内存中查找自然又会提高效率;所以我们必须得合理利用索引。
1)对什么列建索引
数据库默认情况下会对主键建聚集索引,除了这个索引之外还需要在哪些列上建索引呢?这个问题只能具体情况具体分析,要看需要优化的sql语句(通常是查询次数多,查询相应想要高的语句),根据什么列的条件进行查询。
例如:在论坛的数据库中有一张表是帖子回复表,在论坛的应用中用到最多的就是对指定帖子的某一页的回复进行查询,查询回复表的条件是主贴的id;这时候在主贴字段上建索引就势在必然。

2)一定要在主键上建聚集索引吗
通常情况下sql server会自动给主键加上聚集索引,但也有一些例外的情况我们需要把聚集索引建在其他列上,例如我们用到了表分区,而分区的字段不是主键,这时候就需要将聚集索引建在分区的列上。另外如果查询时根据主键查询较少,而根据其他列的查询较频繁,则也可以考虑将聚集索引建在非主键上。单需要注意的是聚集索引的列必须是不易变的列,如果聚集索引变了一会引起聚集索引内的记录的搬迁,造成页page的分离与碎片;二会引起每一个非聚 集索引被修改,以便于所有相关的非聚集索引的行的索引键的值被纠正。这既浪费时间和空间,也导致需要整理的碎片,增加了不必要的开销(每个列重组聚集键)。

3)复合索引(索引有两个以上的列)要注意列顺序
索引在数据库中是以B树的形式存储的。包含A,B两个列的索引会首先根据A列建B树,A列的叶节点上才会开始根据B列建B树。所以包含两个列的索引就需要根据查询条件所在列来决定两个列在索引中的顺序。
可以用下面的sql做实验:


代码如下:

USE [Test]
GO
/****** 对象: Table [dbo].[testIndexOrder] 脚本日期: 05/27/2010 09:11:26 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[testIndexOrder](
[ID] [int] IDENTITY(1,1) NOT NULL,
[FirstName] [nvarchar](20) COLLATE Chinese_PRC_CI_AS NOT NULL,
[LastName] [nvarchar](20) COLLATE Chinese_PRC_CI_AS NOT NULL,
[Desc] [nvarchar](400) COLLATE Chinese_PRC_CI_AS NULL,
CONSTRAINT [PK_testIndexOrder] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** 对象: Index [IX_testIndexOrder] 脚本日期: 05/27/2010 09:11:51 ******/
CREATE NONCLUSTERED INDEX [IX_testIndexOrder] ON [dbo].[testIndexOrder]
(
[FirstName] ASC,
[LastName] ASC
)WITH (SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF) ON [PRIMARY]
GO
declare @i INT;
DECLARE @random varchar(36);
set @i = 0;
while @i < 100000
begin
set @random = newid();
INSERT INTO [testIndexOrder]
(FirstName,LastName,[Desc])
VALUES(
substring(@random,1,8),substring(@random,12,8),@random
);
set @i = @i + 1
end

set statistics time on
select * from [testIndexOrder] where lastname = '6F-4ECA-'
select * from [testIndexOrder] where firstname = 'CAABE009'
set statistics time off

4)索引的个数问题
索引提高查询效率是以降低更新、插入、删除的速度为代价的。每当索引列发生变化时都需要对索引数据进行相应的调整。所以一个表上不可以建太多的索引,除非你完全不在乎修改数据的效率。另外sql server本身会对索引的数量和索引的数据长度有限制,具体请参考
5)在必要时重建索引
Sql server运行一段时间之后就会形成一些索引碎片,这时候就需要重建索引了,有时候重建索引可以起到意想不到的效果。
查看索引碎片,重建索引,可以通过sql server管理器来重建;也可以通过下面的sql语句来实现:


代码如下:

--显示表testIndexOrder的索引碎片情况
DBCC SHOWCONTIG(testIndexOrder)

--重建表的索引
--第一个参数,可以是表名,也可以是表ID。
--第二个参数,如果是'',表示影响该表的所有索引。
--第三个参数,填充因子,即索引页的数据填充程度。如果是,表示每一个索引页都全部填满,此时select效率最高,但以后要插入索引时,就得移动后面的所有页,效率很低。如果是,表示使用先前的填充因子值。
DBCC DBREINDEX(testIndexOrder,'',)

数据库优化是一门复杂的学问,需要不断的学习实践,积累经验。

(0)

相关推荐

  • C#入门之索引器使用实例

    本文实例展示了C#索引器的使用方法,对于C#的初学者来说是很有必要熟练掌握的,具体用法如下: 首先,索引器(Indexer)是C#引入的一个新型的类成员,它使得类中的对象可以像数组那样方便.直观的被引用.索引器非常类似于属性,但索引器可以有参数列表,且只能作用在实例对象上,而不能在类上直接作用.定义了索引器的类可以让您像访问数组一样的使用 [ ] 运算符访问类的成员.(当然高级的应用还有很多,比如说可以把数组通过索引器映射出去等等) 索引器的语法如下: 1.它可以接受1个或多个参数 2.使用th

  • C#索引器简单实例代码

    复制代码 代码如下: public class Fruit { string peach = "a round juicy fruit that has a soft yellow or red skin and a large hard seed in the center, or the tree that this fruit grows on"; string orange = "a round fruit that has a thick orange skin a

  • c#字符串查找某词出现的次数及索引

    字符串方法的使用: indexof(): 有9个重载,具体的请转到F12查看详细内容: 本文使用的是第6个重载: 如果找到该字符串,则为从零开始的索引位置:如果未找到该字符串,则为 -1 有两个参数: string value:要搜索的字符 int startIndex:搜索的起始位置 复制代码 代码如下: class Program    {        static void Main(string[] args)        {            //统计出字符串中,下雪出现的次数

  • 深入理解C#索引器(一种支持参数的属性)与属性的对比

    索引器是一种特殊的类成员,它能够让对象以类似数组的方式来存取,使程序看起来更为直观,更容易编写. 1.索引器的定义C#中的类成员可以是任意类型,包括数组和集合.当一个类包含了数组和集合成员时,索引器将大大简化对数组或集合成员的存取操作.定义索引器的方式与定义属性有些类似,其一般形式如下:时,索引器//this表示的是操作本对象的数组或集合成员,可以简单把它理解成索引器的名字,所以,当相同类型的时候,记得通过参数区分. 复制代码 代码如下: //[修饰符] 数据类型 this[索引类型 index

  • c#索引器详解示例

    1.索引器的定义 C#中的类成员可以是任意类型,包括数组和集合.当一个类包含了数组和集合成员时,索引器将大大简化对数组或集合成员的存取操作. 定义索引器的方式与定义属性有些类似,其一般形式如下: [修饰符] 数据类型 this[索引类型 index] 复制代码 代码如下: {    get{//获得属性的代码}                                                     set{ //设置属性的代码}} 修饰符包括 public,protected,p

  • C#索引器介绍

    索引器是一种特殊的类成员,它能够让对象以类似数组的方式来存取,使程序看起来更为直观,更容易编写. 1.索引器的定义 C#中的类成员可以是任意类型,包括数组和集合.当一个类包含了数组和集合成员时,索引器将大大简化对数组或集合成员的存取操作. 定义索引器的方式与定义属性有些类似,其一般形式如下: 复制代码 代码如下: [修饰符] 数据类型 this[索引类型 index] { get{//获得属性的代码} set{ //设置属性的代码} } 修饰符包括 public,protected,privat

  • 使用asp.net的pageDataSource中时索引问题解决方法

    出现错误情况: 当前页面在数据的除第一页的任何一个页面时,重新条件查询并且是新条件的总页数小于刚才查询得到的页码时,就会出现"索引 20 不是为负数,就是大于行数"的类似的错误! 原因分析: 当查询的数据的页码索引大于1时,重新查询条件时,当前所得数据的页码数又少于上次所得到的页码,所以新查询索引小于上次查询索引,出现索引大于行数的问题. 解决方法: 每次重新查询前把页码索引初始化为1,

  • asp.net gridview的Rowcommand命令中获取行索引的方法总结

    一.通过命令源获取当前行索引. 方法比较多, GridView 的 Command 事件中无法象 DataGrid 那样直接获取行, 法1, GridViewRow drv = ((GridViewRow)(((Button)(e.CommandSource)).Parent.Parent));//CommandSource 引起事件的命令源,(疑问,根据MSDN说的是GridView,如果这样的话这样操作是错误的,但我得到的确实正确的,那说明得到的是BUtton控件,等待以后查证). drv.

  • Asp.Net中索引器的用法分析

    本文实例分析了Asp.Net中索引器的用法.分享给大家供大家参考.具体如下: 索引器定义类似于属性,但其功能与属性并不相同.索引器提供一种特殊的方法编写get和set访问器.属性可以像访问字段一样访问对象的数据,索引器可以使用户像访问数组一样访问类成员. 一.索引器特性 1.get 访问器返回值.set 访问器分配值. 2.this 关键字用于定义索引器. 3.value 关键字用于定义由 set 索引器分配的值. 4.索引器不必根据整数值进行索引,由您决定如何定义特定的查找机制. 5.索引器可

  • asp.net获得数据控件事件索引并获取其中值总结

    复制代码 代码如下: 1.RowCommad //获得索引 int index = ((GridViewRow)(((Button)(e.CommandSource)).Parent.Parent)).RowIndex; 2.RowEditing等 //获得索引 int index = e.NewEditIndex; //获取当前GridViewRow对象 GridViewRow editGridViewRow = autoGridView.Rows[girdviewEditIndex]; //

随机推荐