索引的优化和维护

索引的优化和维护
索引的优化和维护

索引的优化和维护

目的:

通过对数据库中的索引进行优化和维护,提交检索的速度和效率。

原理:

随着数据库的使用,不可避免地对基本表进行插入,更新和删除,这样导致叶子行在索引中被删除,使该索引产生碎片。插入删除越频繁的表,索引碎片的程度也越高。碎片的产生使访问和使用该索引的I/O成本增加。碎片较高的索引必须重建以保持最佳性能。当索引的层数增大时,I/O的成本增加,检索的效率开始降低,oracle建议当索引的层数大于3时,则应当对此索引进行重建以提交效率。随着表记录的增加,相应的索引也要增加。如果一个索引的next值设置不合理(太小),索引段的扩展变得很频繁。索引的extent太多,检索时的速度和效率就会降低。当然还有就是由于一些人为的原因或者系统表的迁移,有可能造成索引的失效,也会降低检索的效率和速度。

通过对索引进行分析,找出碎片比例占索引20%以上的索引;通过查询和索引相关的数据字典和表找出失效的索引、层数大于3的索引和被扩展超过10次的索引;将这些问题索引数据统计到临时表。分别对这些索引进行重建或重新设置 next值(尽量增大,到合理的数值),从而达到优化索引和提高数据库效率的目的。

脚本:

DECLARE

v_index_name varchar2(100);

v_analyze_str varchar2(300);

height number;

lf_rows number;

del_lf_rows number;

v_ex_count number;

v_idx_owner varchar2(30);

v_tab_name varchar2(50);

v_tabspa_name varchar2(50);

v_idx_status varchar2(10);

CURSOR analyze_index IS

SELECT index_name,table_owner,table_name,tablespace_name,status

FROM user_indexes;

BEGIN

OPEN analyze_index;

FETCH analyze_index INTO

v_index_name,v_idx_owner,v_tab_name,v_tabspa_name,v_idx_status;

WHILE analyze_index%FOUND LOOP

if v_idx_status ='INVALID' then

insert into lifemenu.index_stats_prob

values(v_index_name,null,null,null,

‘该索引已失效’,v_idx_owner,v_tab_name,v_tabspa_name,v_idx_status);

end if;

if v_idx_status ='VALID' then

v_analyze_str := 'analyze index '||v_index_name||' validate structure';

EXECUTE IMMEDIATE v_analyze_str;

SELECT HEIGHT,DECODE(LF_ROWS,0,1,LF_ROWS),DEL_LF_ROWS

INTO height,lf_rows,del_lf_rows

FROM index_stats;

if (del_lf_rows/lf_rows)>0.2 then

insert into lifemenu.index_stats_prob

values(v_index_name,del_lf_rows/lf_rows,null,v_ex_count,'该索引的碎片太多,建议重建',v_idx_owner,v_tab_name,v_tabspa_name,v_idx_status);

end if;

if height>=4 and (del_lf_rows/lf_rows) <=0.2 then

insert into lifemenu.index_stats_prob

values(v_index_name,null,height,v_ex_count,'该索引的层数超过3,建议重建',v_idx_owner,v_tab_name,v_tabspa_name,v_idx_status);

end if;

select count(*)

into v_ex_count

from user_extents

where segment_name =v_index_name;

if v_ex_count>=11 and (del_lf_rows/lf_rows)<=0.2 and height<4 then

insert into lifemenu.index_stats_prob

values(v_index_name,null,null,v_ex_count,'该索引扩展超过10次,建议重建时增大参数next',v_idx_owner,v_tab_name,v_tabspa_name,v_idx_status);

end if;

end if;

commit;

v_index_name :='';

v_analyze_str :='';

v_idx_status :='';

FETCH analyze_index INTO

v_index_name,v_idx_owner,v_tab_name,v_tabspa_name,v_idx_status;

END LOOP;

CLOSE analyze_index;

END;

执行结果:

执行结果存储在表index_stats_prob中,表的结构和说明如下:

create table INDEX_STATS_PROB

(

INDEX_NAME VARCHAR2(30) not null,//索引名称

FRAG_PCT NUMBER, //碎片比例

HEIGHT NUMBER, //索引层数

EXTENT_TIME NUMBER, //扩展次数

COM VARCHAR2(50), //建议处理方法

OWNER VARCHAR2(30) not null,//所属用户

TABLE_NAME VARCHAR2(50), //所属表

TABLESPACE_NAME VARCHAR2(50), //所在表空间

STATUS VARCHAR2(10) //状态

)

其中问题索引主要就有四类:

1 碎片比例大于20%的

2 索引层数大于3的且不属于第一类的

3 索引扩展次数超过10的且不属于第一类和第二类的

4 失效的索引

之所以这样处理,是因为碎片比较多的问题索引必须进行处理,其次是层数多的索引,再其次是扩展次数比较多的索引。

在测试数据库ld05sh中的执行结果中,没有发现第二类和第四类的问题索引。

下列是分别在各个用户下执行脚本所耗费的时间的列表:

处理建议:

1.对于第一类和第二类问题索引,即碎片比例大于20%的问题索引和索引层数大于3的且不属于第一类的,都建议进行重建。可以执行下列语句来找出这些索引。同时我们对这两类问题索引也提供了它们扩展的次数,因此如果发现它们被扩展的次数过大,那么在重建的时候也要注意增大索引的next参数。

SELECT *

FROM INDEX_STATS_PROB

WHERE FRAG_PCT IS NOT NULL OR HEIGHT IS NOT NULL

ORDER BY FRAG_PCT DESC;

重建语句如下:

alter index 用户名.索引名 rebuild

tablespace 表空间名

storage(initial 初始值 next 扩展值)

nologging

如果出于空间或其他考虑,不能重建索引,可以整理索引:

alter index用户名.索引名 coalesce

2.对于第三类索引,由于发现在ld05sh中此类索引特别多,所以建议重建扩展次数在50次以上的索引,当然如果在其他环境中发现这类索引的数量不是很多,需要综合考虑,按照扩展次数的多少来确定重建的优先次序,即扩展次数越多的,越优先考虑重建,重建时主要是增大索引的next参数。

执行下列语句来找出这些索引:

SELECT *

FROM INDEX_STATS_PROB

WHERE FRAG_PCT IS NULL AND HEIGHT IS NULL AND EXTENT_TIME>10

ORDER BY EXTENT_TIME DESC;

重建语句相同,注意重建时要增大next 参数:

alter index 用户名.索引名 rebuild

tablespace 表空间名

storage(initial 初始值next 扩展值)

nologging

3.重建索引后,原有的索引被删除,这样会造成表空间的碎片。

整理表空间的碎片alter tablespace 表空间名 coalesce

4. 另外,优化索引还有一些普遍的原则,如:

1)定期对数据更新(主要是删除)频繁的表重建索引

2)建议索引不要建立在系统表空间内

3)建议索引建立在db_block_size比较大的表空间中

4)记录太少的表,应当少建或不建索引;经常处理的业务表(插入、删除、修改),应在查询允许的情况下尽量减少索引。

具体操作:

登录要分析的数据库

在lifemenu用户下创建存放分析数据的表index_stats_prob,脚本如下:

create table INDEX_STATS_PROB

(

INDEX_NAME VARCHAR2(30) not null,

FRAG_PCT NUMBER,

HEIGHT NUMBER,

EXTENT_TIME NUMBER,

COM VARCHAR2(50),

OWNER VARCHAR2(30) not null,

TABLE_NAME VARCHAR2(50),

TABLESPACE_NAME VARCHAR2(50),

STATUS VARCHAR2(10)

)

将此表授权给其他的用户:

grant all on index_stats_prob to 用户名

用其他用户登录要进行索引优化的数据库,执行PL/SQL脚本,然后参照处理建议对索引进行重建,从而达到优化索引,提高效率的目的。

各个用户下的执行时间都不同,具体可以参照执行结果中的脚本耗费时间来设计脚本执行计划。

验证说明:

重建索引后,检索的速度和效率都会得到提高,用户可以通过前后的检索所需时间的比较来验证。

建议:

1.首先需要肯定的一点,该文章总结的非常好,基本上考虑到了在实际使用过程中对索引维护尤其是在判断索引要不要重建的问题。

2.一般情况下,建议对数据库统计信息的收集采用dbms_stats来进行。

3.需要注意的是‘3)建议索引建立在db_block_size比较大的表空间中’,这句话需要调整为,如果你对数据库的表和索引根据业务需求进行优化,制定了该表和索引的基本数据块的大小,并且相应的创建了相应数据块大小的表空间,而且在数据库内存参数中也要相应的运用不同数据块大小的内存的情况下,需要注意该用法。在一般的情况下,没有对表和索引的数据块大小进行设计,默认采用数据库db_block_size的大小,表空间也没有考虑不同的数据块大小的设置,所以,简单起见,就不需要考虑它了。换句话说,想要考虑,就必须从全局的角度来考虑和设计。

4.明显看到在测试系统中信息收集的PL/SQL执行的效率并不是太高,当然选择在数据库维护窗口阶段执行,还是可以的。

5.从以上脚本来看,建议先进行评估对数据库进行统计信息的收集,包括表和索引收集对业务运行的影响,收集的时间长度估算等,然后再进行统计信息的收集,收集后,才来分析那些20%的高水位的指标的索引进行重新创建。否则,有可能按照规则筛选出来的结果很多,在实际实施的时候,限制的因素就多,存储空间,维护时间,系统资源处理能力以及重新创建后产生的效果等。

6.在确定了需要创建的索引之后,就需要分析创建索引的可行性。

1)。创建索引执行过程的时间。

2)。创建索引的过程对系统运行的影响,尤其是索引扩展段比较多的情况下,后台进程SMON 需要清理临时段的时间也需要考虑。

3)。重建索引所需要注意索引的存储参数以及表空间的存储参数控制。

4)。结合业务应用对表和索引的使用,尽量对索引的重建有个比较清晰的认识,尽量做到全局的权衡。

5)。尽量具体索引问题具体分析解决。

mysql数据库索引优化

我们首先讨论索引,因为它是加快查询的最重要的工具。还有其他加快查询的[url=javascript:;]技术[/url],但是最有效的莫过于恰当地使用索引了。在MySQL 的邮件清单上,人们通常询问关于使查询更快的问题。在大量的案例中,都是因为表上没有索引,一般只要加上索引就可以立即解决问题。但这样也并非总是有效,因为优化并非总是那样简单。然而,如果不使用索引,在许多情形下,用其他手段改善性能只会是浪费时间。应该首先考虑使用索引取得最大的性能改善,然后再寻求其他可能有帮助的技术。 本节介绍索引是什么、它怎样改善查询性能、索引在什么情况下可能会降低性能,以及怎样为表选择索引。下一节,我们将讨论MySQL 的查询优化程序。除了知道怎样创建索引外,了解一些优化程序的知识也是有好处的,因为这样可以更好地利用所创建的索引。某些编写查询的方法实际上会妨碍索引的效果,应该避免这种情况出现。(虽然并非总会这样。有时也会希望忽略优化程序的作用。我们也将介绍这些情况。) 索引对单个表查询的影响 索引被用来快速找出在一个列上用一特定值的行。没有索引,MySQL不得不首先以第一条记录开始并然后读完整个表直到它找出相关的行。表越大,花费时间越多。如果表对于查询的列有一个索引,MySQL能快速到达一个位置去搜寻到数据文件的中间,没有必要考虑所有数据。如果一个表有1000 行,这比顺序读取至少快100倍。注意你需要存取几乎所有1000行,它较快的顺序读取,因为此时我们避免磁盘寻道。 例如对下面这样的一个student表: mysql>SELECT * FROM student +------+---------+---------+---------+---------+ | id | name | english | chinese | history | +------+---------+---------+---------+---------+ | 12 | Tom | 66 | 93 | 67 | | 56 | Paul | 78 | 52 | 75 | | 10 | Marry | 54 | 89 | 74 | | 4 | Tina | 99 | 83 | 48 | | 39 | William | 43 | 96 | 52 | | 74 | Stone | 42 | 40 | 61 | | 86 | Smith | 49 | 85 | 78 | | 37 | Black | 49 | 63 | 47 | | 89 | White | 94 | 31 | 52 | +------+---------+---------+---------+---------+ 这样,我们试图对它进行一个特定查询时,就不得不做一个全表的扫描,速度很慢。例如,我们查找出所有english成绩不及格的学生: mysql>SELECT name,english FROM student WHERE english<60; +---------+---------+ | name | english | +---------+---------+ | Marry | 54 | | William | 43 | | Stone | 42 | | Smith | 49 |

优化-索引

优化-索引.txt为什么我们在讲故事的时候总要加上从前?开了一夏的花,终落得粉身碎骨,却还笑着说意义。人们在使用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上的组合索引

索引的使用原则

索引的优点:这个显而易见,正确的索引会大大提高数据查询,对结果进行排序、分组的操作效率。 索引的缺点:优点显而易见,同样缺点也是显而易见: 1:创建索引需要额外的磁盘空间,索引最大一般为表大小的1.2倍左右。 2:在表数据修改时,例如增加,删除,更新,都需要维护索引表,这是需要系统开销的。 3:不合理的索引设计非但不能利于系统,反而会使系统性能下降。例如我们在一个创建有非聚集索引的列上做范围查询,此列的索引不会起到任何的优化效果,反而由于数据的修改而需要维护索引表,从而影响了对数据修改的性能。 实际例子:还是拿前两篇文章的学生表来讲吧,要查询成绩在50分以上的学生信息select * from student where score>50。学生表包含了100000行记录,而且学分是随机生成的,这样从数据量以及数据分布上都有一定的保障。 第一种情况:学生表有索引。 1:存在聚集索引,但聚集索引不在学分上,这里只分析学分不是聚集索引的情况。 (1):学分上没有索引。此时SQL会通过聚集索引来查找数据,这点估计大家都会知道。 (2):学分上有索引。这种情况,SQL会使用上学分上的索引吗?这个问题估计不是每个人都能回答正确的。既然学分上有索引,而where中又有此列,理应使用了索引,但实际情况并没有使用索引。因为出现了范围查找,如果一个索引一个索引的比较,在性能上比起直接按聚集索引查找全部数据后再过滤来的差。那学分上的索引什么时候 SQL会优先考虑呢?当score指定为一个具体值时,就能使用学分索引查找了。从下图的SQL执行计

划可以得知。 2:不存在聚集索引。 (1):在学分上没有索引,其它字段有索引,这种情况就会出现表扫描。 (2):在学分上有索引,是否会按照学分上的索引进行查找呢?由于上面的表数据量也不少,一般会认为SQL不会采用表扫描,因为会查找全部记录,但实际情况表明SQL 对于范围查询也行采用表扫描而不是按学生索引查询。我们也可以强制SQL按学分查询,于是有下面的SQL执行计划比较,我们可以清楚的看出,强制使用学分做为索引查询比表搜索

如何优化数据库,提高查询效率

龙源期刊网 https://www.360docs.net/doc/7815724163.html, 如何优化数据库,提高查询效率 作者:代鸿彬 来源:《学习与科普》2019年第10期 摘要:随着信息时代的到来,生活和工作当中已经无法避免的需要和计算机打交道,和 计算机打交道的同时就必须要用到数据库。数据库系统是计算机当中的一项重要系统,储存在用户的关键信息,不仅对个人影响很大,同时对企事业单位也有着重要影响。 关键词:信息时代;数据库;索引 数据库是信息的载体也是数据的最佳表现形式,它的共享性导致了数据会被大量的搜索查询,为了提高查询的效率,就不得不对数据库进行优化。 一、利用索引进行优化。 索引是数据库的重要组成部分,也是使用者根据需要进行查询最直接的方法,优化索引可以提高查询的效率。当前的数据库当中大部分还是使用国际商业机器公司以前的索引顺序存取方法,对于用户来说肯定会选择方便、快捷的索引方式,怎么方便怎么来。在建立索引的时候针对不同的内容,需要建立不同的连接方式,但是随着用户的增多,查询内容和方向的多元化,这就造成了在实际工作当中经常会有使用频率很少的索引出现,甚至也会出现没有查询所需的索引,这种情况可以通过查询优化器进行自动生成的索引进行查询。对于使用频率较为频繁的列,需要对其进行排序或者分组的列上建立索引时,要优化索引提高效率,对于使用频率很少的列可以不建立索引。 二、简化排序进行优化。 对于部分企事业单位需要排序的内容很多时,就要使用大型数据表来满足查询需求,但是大型数据表涉及的内容很多,为了避免出现重复排序的现象需要对数据表进行简化。在大型数据表当中有一部分的内容可以自动进行排序的次序输出,这时就可以直接利用查询优化器进行优化,将复杂的排序简单化,从而提高索引查询效率。需要排序的列对索引优化影响较大,就像语言当中的ORDER BY 或者GROUP BY句子当中的列次序和索引当中的列次序基本是不同的,但是排序的列可通过表的不同形式表现出来。通过简化排序避免了重复的排序,并且将数据库进行了合理的合并。如果不进行简化排序,就需要将排序的范围进行缩小简化,从而提高查询使用的效率。 三、大型表行数据库存取的合理消除。 数据库系统的存储量是有上限的,所有的索引内容都占有数据库空间,尤其是大型数据表占有的空间更大,将会造成索引时间变长。但是大型表行数据有些内容是不必要的,在进行索引查詢时,数据表当中的存取顺序对查询的效率有直接的影响。例如需要采用存取策略时,通

SQLSERVER索引及优化详解

SqlServer索引及优化详解 (一)深入浅出理解索引结构 实际上,您可以把索引理解为一种特殊的目录。微软的SQL SERVER提供了两种索引:聚集索引(clustered index,也称聚类索引、簇集索引)和非聚集索引(nonclustered index,也称非聚类索引、非簇集索引)。下面,我们举例来说明一下聚集索引和非聚集索引的区别:其实,我们的汉语字典的正文本身就是一个聚集索引。比如,我们要查“安”字,就会很自然地翻开字典的前几页,因为“安”的拼音是“an”,而按照拼音排序汉字的字典是以英文字母“a”开头并以“z”结尾的,那么“安”字就自然地排在字典的前部。如果您翻完了所有以“a”开头的部分仍然找不到这个字,那么就说明您的字典中没有这个字;同样的,如果查“张”字,那您也会将您的字典翻到最后部分,因为“张”的拼音是“zhang”。也就是说,字典的正文部分本身就是一个目录,您不需要再去查其他目录来找到您需要找的内容。 我们把这种正文内容本身就是一种按照一定规则排列的目录称为“聚集索引”。如果您认识某个字,您可以快速地从自动中查到这个字。但您也可能会遇到您不认识的字,不知道它的发音,这时候,您就不能按照刚才的方法找到您要查的字,而需要去根据“偏旁部首”查到您要找的字,然后根据这个字后的页码直接翻到某页来找到您要找的字。但您结合“部首目录”和“检字表”而查到的字的排序并不是真正的正文的排序方法,比如您查“张”字,我们可以看到在查部首之后的检字表中“张”的页码是672页,检字表中“张”的上面是“驰”字,但页码却是63页,“张”的下面是“弩”字,页面是390页。很显然,这些字并不是真正的分别位于“张”字的上下方,现在您看到的连续的“驰、张、弩”三字实际上就是他们在非聚集索引中的排序,是字典正文中的字在非聚集索引中的映射。我们可以通过这种方式来找到您所需要的字,但它需要两个过程,先找到目录中的结果,然后再翻到您所需要的页码。我们把这种目录纯粹是目录,正文纯粹是正文的排序方式称为“非聚集索引”。通过以上例子,我们可以理解到什么是“聚集索引”和“非聚集索引”。进一步引申一下,我们可以很容易的理解:每个表只能有一个聚集索引,因为目录只能按照一种方法进行排序。 (二)何时使用聚集索引或非聚集索引 下面的表总结了何时使用聚集索引或非聚集索引(很重要)。

informix数据库索引使用与维护

informix数据库索引使用与维护.txt都是一个山的狐狸,你跟我讲什么聊斋,站在离你最近的地方,眺望你对别人的微笑,即使心是百般的疼痛只为把你的一举一动尽收眼底.刺眼的白色,让我明白什么是纯粹的伤害。informix数据库索引使用与维护 王增印 对于我们广泛使用的informix数据库系统,它能使我们及时快速准确地管理和使用数据,而要使我们加快数据使用的速度和效率,最重要的一点是要能正确合理地对数据库建立索引。因此为在工作中对数据使用更合理高效,informix数据库索引建立、限制及适用范围及应用维护等问题作一表述。 给表中的字段加索引能帮助我们快捷的使用数据库,但是如果表加的索引不当非但不能加快对数据库的访问,甚至造成informix-sql的错误,中止对库的管理。因而,在建立库表之前需详细了解它的适用范围及限制。 在如下情况下适于建立数据库索引: a、适用于对大型数据库查找并连续输出,如同查找字典越厚越显出索引的重要性。 b、给连接字段加索引,当你库中包含很多表时,往往第一张表中至少有一个连接字段,则给连接字段加索引。(如会计帐务中户主帐与明细帐校验核对时,须连续对户主帐中每一项在明细帐中查找有效值,而户主帐与明细帐中在帐号字段上是连接的,而此时使用索引比不使用大大提高了工效,如果这两个帐表的记录数都达数千时,不建索引将不可能完成这项工作。) c、自动索引,如果你执行的是包含两个表的连接操作且连接字段不加索引的select语句,则rdsql在执行连接操作之前给记录数较多的表自动建立临时索引,检索操作完成后,索引消失,它有利于无索引检索速度的改善。 d、对于经常要查找和排序的字段,它可以在你使用一段时间后,确信要经常查找和排序的字段,你可随时加上。 e、须至少是一个表且其中多于200个记录,虽然informix-spl对于一个表建立索引的数量及表记录多少是不限制的,但建立索引的同时,对于录入和修改数据时,sql都要更新表和索引,同时索引也占用磁盘空间,即对于一个小表建立索引不仅减慢速度还多占空间。 f、要避免给含大量重复值的字段加索引,它会显著减慢删除数据和改变索引字段值的操作。 对数据库建立的索引有如下限制: a、建索引的字段或字组长度不应超过120字节,否则会造成sql错误。 b、被加索引的字段,如果其中有6000个共同项时,也会导致sql错误。

MYSQL索引和优化详细说明教程

MYSQL索引和优化详细说明教程 2008-05-16 15:59 MYSQL索引和优化 一、什么是索引? 索引用来快速地寻找那些具有特定值的记录,所有MySQL索引都以B-树的形式保存。如果没有索引,执行查询时MySQL必须从第一个记录开始扫描整个表的所有记录,直至找到符合要求的记录。表里面的记录数量越多,这个操作的代价就越高。如果作为搜索条件的列上已经创建了索引,MySQL无需扫描任何记录即可迅速得到目标记录所在的位置。如果表有1000个记录,通过索引查找记录至少要比顺序扫描记录快100倍。 假设我们创建了一个名为people的表: 然后,我们完全随机把1000个不同name值插入到people表。 可以看到,在数据文件中name列没有任何明确的次序。如果我们创建了name 列的索引,MySQL将在索引中排序name列: 对于索引中的每一项,MySQL在内部为它保存一个数据文件中实际记录所在位置的“指针”。因此,如果我们要查找name等于“Mike”记录的peopleid(SQL 命令为“SELECT peopleid FROM people WHERE name=\’Mike\’;”),MySQL 能够在name的索引中查找“Mike”值,然后直接转到数据文件中相应的行,准确地返回该行的peopleid(999)。在这个过程中,MySQL只需处理一个行就可以返回结果。如果没有“name”列的索引,MySQL要扫描数据文件中的所有记录,即1000个记录!显然,需要MySQL处理的记录数量越少,则它完成任务的速度就越快。 二、索引的类型 MySQL提供多种索引类型供选择: 普通索引 这是最基本的索引类型,而且它没有唯一性之类的限制。普通索引可以通 过以下几种方式创建:

sql优化方案讲解

Sql优化方案 一.数据库优化技术 1.索引(强烈建议使用) 1.1优点 创建索引可以大大提高系统的性能。 第一,通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。 第二,可以大大加快数据的检索速度,这也是创建索引的最主要的原因。 第三,可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。 第四,在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。 第五,通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。 1.2 缺点 第一,创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加。第二,索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大。 第三,当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这样就降低了数据的维护速度。 1.3 使用准则 索引是建立在数据库表中的某些列的上面。因此,在创建索引的时候,应该仔细考虑在哪些列上可以创建索引,在哪些列上不能创建索引。 一般来说,应该在这些列上创建索引。 第一,在经常需要搜索的列上,可以加快搜索的速度;

第二,在作为主键的列上,强制该列的唯一性和组织表中数据的排列结构; 第三,在经常用在连接的列上,这些列主要是一些外键,可以加快连接的速度;第四,在经常需要根据范围进行搜索的列上创建索引,因为索引已经排序,其指定的范围是连续的; 第五,在经常需要排序的列上创建索引,因为索引已经排序,这样查询可以利用索引的排序,加快排序查询时间; 第六,在经常使用在WHERE子句中的列上面创建索引,加快条件的判断速度。 同样,对于有些列不应该创建索引。一般来说,不应该创建索引的的这些列具有下列特点: 第一,对于那些在查询中很少使用或者参考的列不应该创建索引。这是因为,既然这些列很少使用到,因此有索引或者无索引,并不能提高查询速度。相反,由于增加了索引,反而降低了系统的维护速度和增大了空间需求。 第二,对于那些只有很少数据值的列也不应该增加索引。这是因为,由于这些列的取值很少,例如人事表的性别列,在查询的结果中,结果集的数据行占了表中数据行的很大比例,即需要在表中搜索的数据行的比例很大。增加索引,并不能明显加快检索速度。 第三,对于那些定义为text, image和bit数据类型的列不应该增加索引。这是因为,这些列的数据量要么相当大,要么取值很少。 第四,当修改性能远远大于检索性能时,不应该创建索引。这是因为,修改性能和检索性能是互相矛盾的。当增加索引时,会提高检索性能,但是会降低修改性能。当减少索引时,会提高修改性能,降低检索性能。因此,当修改性能远远大于检索性能时,不应该创建索引。 1.4 总结 1)索引提高了数据库的检索性能,但一定程度上牺牲了修改性能。因此适用于“多查询少修改”(insert,update,delete)的表。 2)对此类表中的外键,需要分组,排序或作为检索条件的字段建立索引 3)对此类表中查询使用少,字段取值少,字段数据量大的不应创建索引

索引的优点和缺点

一、为什么要创建索引呢(优点)? 这是因为,创建索引可以大大提高系统的性能。 第一,通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。 第二,可以大大加快数据的检索速度,这也是创建索引的最主要的原因。 第三,可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。 第四,在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。第五,通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。 二、建立方向索引的不利因素(缺点) 也许会有人要问:增加索引有如此多的优点,为什么不对表中的每一个列创建一个索引呢?这种想法固然有其合理性,然而也有其片面性。虽然,索引有许多优点,但是,为表中的每一个列都增加索引,是非常不明智的。这是因为,增加索引也有许多不利的一个方面。 第一,创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加。 第二,索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大。 第三,当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这样就降低了数据的维护速度。 三、创建方向索引的准则 索引是建立在数据库表中的某些列的上面。因此,在创建索引的时候,应该仔细考虑在哪些列上可以创建索引,在哪些列上不能创建索引。 一般来说,应该在这些列上创建索引。 第一,在经常需要搜索的列上,可以加快搜索的速度; 第二,在作为主键的列上,强制该列的唯一性和组织表中数据的排列结构; 第三,在经常用在连接的列上,这些列主要是一些外键,可以加快连接的速度; 第四,在经常需要根据范围进行搜索的列上创建索引,因为索引已经排序,其指定的范围是连续的; 第五,在经常需要排序的列上创建索引,因为索引已经排序,这样查询可以利用索引的排序,加快排序查询时间; 第六,在经常使用在WHERE子句中的列上面创建索引,加快条件的判断速度。 同样,对于有些列不应该创建索引。一般来说,不应该创建索引的的这些列具有下列特点: 第一,对于那些在查询中很少使用或者参考的列不应该创建索引。这是因为,既然这些列很少使用到,因此有索引或者无索引,并不能提高查询速度。相反,由于增加了索引,反而降低了系统的维护速度和增大了空间需求。 第二,对于那些只有很少数据值的列也不应该增加索引。这是因为,由于这些列的取值很少,例如人事表的性别列,在查询的结果中,结果集的数据行占了表中数据行的很大比例,即需要在表中搜索的数据行的比例很大。增加索引,并不能明显加快检索速度。 第三,对于那些定义为text, image和bit数据类型的列不应该增加索引。这是因为,这些列的数据量要么相当大,要么取值很少。 第四,当修改性能远远大于检索性能时,不应该创建索引。这是因为,修改性能和检索性能是互相矛盾的。当增加索引时,会提高检索性能,但是会降低修改性能。当减少索引时,会提高修改性能,降低检索性能。因此,当修改性能远远大于检索性能时,不应该创建索引。

浅谈MySQL索引分析和优化

MySQL索引分析和优化列:

由于索引文件以B-树格式保存,MySQL能够立即转到合适的firstname,然后再转到合适的lastname,最后转到合适的age。在没有扫描数据文件任何一个记录的情况下,MySQL就正确地找出了搜索的目标记录! 那么,如果在firstname、lastname、age这三个列上分别创建单列索引,效果是否和创建一个firstname、lastname、age的多列索引一样呢?答案是否定的,两者完全不同。当我们执行查询的时候,MySQL只能使用一个索引。如果你有三个单列的索引,MySQL会试图选择一个限制最严格的索引。但是,即使是限制最严格的单列索引,它的限制能力也肯定远远低于firstname、lastname、age这三个列上的多列索引。

下面我们就来看看这个EXPLAIN分析结果的含义。 table:这是表的名字。 type:连接操作的类型。下面是MySQL文档关于ref连接类型的说明: “对于每一种与另一个表中记录的组合,MySQL将从当前的表读取所有带有匹配索引值的记录。如果连接操作只使用键的最左前缀,或者如果键不是UNIQUE或PRIMARY KEY类型(换句话说,如果连接操作不能根据键值选择出唯一行),则MySQL使用ref连接类型。如果连接操作所用的键只匹配少量的记录,则ref是一种好的连接类型。” 在本例中,由于索引不是UNIQUE类型,ref是我们能够得到的最好连接类型。 如果EXPLAIN显示连接类型是“ALL”,而且你并不想从表里面选择出大多数记录,那么MySQL的操作效率将非常低,因为它要扫描整个表。你可以加入更多的索引来解决这个问题。预知更多信息,请参见MySQL的手册说明。 possible_keys: 可能可以利用的索引的名字。这里的索引名字是创建索引时指定的索引昵称;如果索引没有昵称,则默认显示的是索引中第一个列的名字(在本例中,它是“firstname”)。默认索引名字的含义往往不是很明显。 Key:它显示了MySQL实际使用的索引的名字。如果它为空(或NULL),则MySQL不使用索引。 key_len:索引中被使用部分的长度,以字节计。在本例中,key_len是102,其中firstname 占50字节,lastname占50字节,age占2字节。如果MySQL只使用索引中的firstname部分,则key_len将是50。 ref:它显示的是列的名字(或单词“const”),MySQL将根据这些列来选择行。在本例中,MySQL根据三个常量选择行。 rows:MySQL所认为的它在找到正确的结果之前必须扫描的记录数。显然,这里最理想的数字就是1。 Extra:这里可能出现许多不同的选项,其中大多数将对查询产生负面影响。在本例中,MySQL 只是提醒我们它将用WHERE子句限制搜索结果集。 索引的缺点 到目前为止,我们讨论的都是索引的优点。事实上,索引也是有缺点的。 首先,索引要占用磁盘空间。通常情况下,这个问题不是很突出。但是,如果你创建每一种可能列组合的索引,索引文件体积的增长速度将远远超过数据文件。如果你有一个很大的表,索引文件的大小可能达到操作系统允许的最大文件限制。 第二,对于需要写入数据的操作,比如DELETE、UPDATE以及INSERT操作,索引会降低它们的速度。这是因为MySQL不仅要把改动数据写入数据文件,而且它还要把这些改动写入索引文件。 【结束语】在大型数据库中,索引是提高速度的一个关键因素。不管表的结构是多么简单,一次500000行的表扫描操作无论如何不会快。如果你的网站上也有这种大规模的表,那么你确实应该花些时间去分析可以采用哪些索引,并考虑是否可以改写查询以优化应用。要了解更多信息,请参见MySQL manual。另外注意,本文假定你所使用的MySQL是3.23版,部分查询不能在3.22版MySQL上执行。

SQL Server索引设计和调优技巧大全

SQL Server索引设计与调优

SQL Server索引技巧设计与调优 如果你想极大提高SQL Server性能,本篇指南中提到的索引将是您最佳选择之一。在本文指南中你将了解如何设计最佳SQL Server索引、如何调整SQL Server索引等一系列内容,让你现存的SQL Server索引能够发挥最佳效能。 SQL Server索引设计 SQL Server集簇索引的设计 SQL Server中集群索引设计对SQL Server数据库系统性能和未来的维护十分重要。在本文中你将了解到为什么集群索引应该是静态、随着时间推移而增长、了解它们是如何使用多对多表的。此外,在文中你还会知道在SQL Server 2005中分区表概念是怎样影响集群索引的。 设计SQL Server集簇索引以提升性能(一) 设计SQL Server集簇索引以提升性能(二) 如何创建SQL Server索引 索引的作用应该是确保主要性能。本节你将会学到如何清除那些没有价值的索引并识别推荐索引保证你的SQL Server索引能发挥它的最大效能。 SQL Server索引创建技巧(上) SQL Server索引创建技巧(下) 如何优化索引

索引SQL Server数据库既是艺术也是技术。我们必须根据设计和编码来选择正确的索引。但是,当测试索引设计时,我们可能发现它对系统性能的提高并没有达到我们的要求。我们必须通过学习索引字段、聚簇索引、主键以及索引配置来创建最佳设计的SQL Server索引。文中介绍了一些设计索引时的常见问题。 专家详解SQL Server 2000创建和优化索引 索引的能与不能 在这一系列的问题和答案中,我们将了解索引列和数据库的正确含义,避免出现页面拆分的情况并了解SQL Server 2000的能与不能。 SQL Server 2000索引的能与不能(DO和DON’T) 改进性能的分区索引 SQL Server 2005索引分区允许你将特定索引符合分散到多个文件。本文中还介绍了如何用分区数据创建索引的方法。 改进SQL Server 2005性能的分区索引(上) 改进SQL Server 2005性能的分区索引(下) 聚簇索引和非聚簇索引的区别 什么时候使用聚簇索引或非聚簇索引呢?回答这个问题有点难度,坦白地说,我即将给出的答案是一个流传已久的标准数据库管理员的回答:“具体问题具体分析”。有大量因素影响何时以及何地进行索引创建。幸好只有两个选择,但分析这两个选择的优缺点都相当复杂。

优化与索引

@对表的访问 1、全表扫描 1、对表所有的块,进行访问,采用多块读的方式 2、设置多块读的参数 SQL> show parameter db_file_multiblock NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ db_file_multiblock_read_count integ er 16 上面设置的多块读是16,Oracle读的时候尽量每次读取是16块,Oracle不害怕多块读,害怕的是产生多次物理io的读取 成本计算: cost:标的块数 /db_file_multiblock_read_count db_file_multiblock_read_count这个参数设置的大小会影响Oracle在计算的时候的一个成本。如果说这个参数设置的足够大,那么就会导致好多表不走索引,会去走全表扫描 3、filter:过滤 读取了大量的数据,然后使用条件过滤了大量的数据,剩余了少量的数据行 4、filter是否合适,判断标准 1、读取了多少数据 2、取出了多少数据,过滤了多少数据 假设过滤掉99%的数据,那么过滤是失败的 90%以上的数据过滤掉,我们就应该考虑这个过滤的价值,也就是cost 2、走索引不使用多块读 1、成本计算: 访问索引的成本+索引访问表的成本 访问索引的成本:索引树的高度+叶子节点的块数 索引访问表的成本:行数*集群因子/总行数 2、集群因子: 最小值就是表的块数 最大值就是表的行数 集群因子高带来的问题: 1、计算走索引的时候的成本高 2、额外的占用过多的buffer 3、额外的增加物理io 3、取得数据量一般<5%~20%的话我们建议走索引

SQL索引详解(优化数据库)

SQL索引一步到位 SQL索引在数据库优化中占有一个非常大的比例,一个好的索引的设计,可以让你的效率提高几十甚至几百倍,在这里将带你一步步揭开他的神秘面纱。 1.1 什么是索引? SQL索引有两种,聚集索引和非聚集索引,索引主要目的是提高了SQL Server系统的性能,加快数据的查询速度与减少系统的响应时间 下面举两个简单的例子: 图书馆的例子:一个图书馆那么多书,怎么管理呢?建立一个字母开头的目录,例如:a开头的书,在第一排,b开头的在第二排,这样在找什么书就好说了,这个就是一个聚集索引,可是很多人借书找某某作者的,不知道书名怎么办?图书管理员在写一个目录,某某作者的书分别在第几排,第几排,这就是一个非聚集索引 字典的例子:字典前面的目录,可以按照拼音和部首去查询,我们想查询一个字,只需要根据拼音或者部首去查询,就可以快速的定位到这个汉字了,这个就是索引的好处,拼音查询法就是聚集索引,部首查询就是一个非聚集索引. 看了上面的例子,下面的一句话大家就很容易理解了:聚集索引存储记录是物理上连续存在,而非聚集索引是逻辑上的连续,物理存储并不连续。就像字段,聚集索引是连续的,a后面肯定是b,非聚集索引就不连续了,就像图书馆的某个作者的书,有可能在第1个货架上和第10个货架上。还有一个小知识点就是:聚集索引一个表只能有一个,而非聚集索引一个表可以存在多个。 1.2 索引的存储机制 首先,无索引的表,查询时,是按照顺序存续的方法扫描每个记录来查找符合条件的记录,这样效率十分低下,举个例子,如果我们将字典的汉字随即打乱,没有前面的按照拼 音或者部首查询,那么我们想找一个字,按照顺序的方式去一页页的找,这样效率有多底,大家可以想象。 聚集索引和非聚集索引的根本区别是表记录的排列顺序和与索引的排列顺序是否一致,其实理解起来非常简单,还是举字典的例子:如果按照拼音查询,那么都是从a-z的,是 具有连续性的,a后面就是b,b后面就是c,聚集索引就是这样的,他是和表的物理排列顺序是一样的,例如有id为聚集索引,那么1后面肯定是2,2后面肯定是3,所以说这样的搜索顺序的就是聚集索引。非聚集索引就和按照部首查询是一样是,可能按照偏房查询的时候,根据偏旁‘弓’字旁,索引出两个汉字,张和弘,但是这两个其实一个在100页,一个在1000页,(这里只是举个例子),他们的索引顺序和数据库表的排列顺序是不一样的,这个样的就是非聚集索引。 原理明白了,那他们是怎么存储的呢?在这里简单的说一下,聚集索引就是在数据库 被开辟一个物理空间存放他的排列的值,例如1-100,所以当插入数据时,他会重新排列 整个整个物理空间,而非聚集索引其实可以看作是一个含有聚集索引的表,他只仅包含原表中非聚集索引的列和指向实际物理表的指针。他只记录一个指针,其实就有点和堆栈差不多的感觉了

mysql性能优化-慢查询分析、优化索引和配置

mysql性能优化-慢查询分析、优化索引和配置目录 一、优化概述 二、查询与索引优化分析 1性能瓶颈定位 Show命令 慢查询日志 explain分析查询 profiling分析查询 2索引及查询优化 三、配置优化 1) max_connections 2) back_log 3) interactive_timeout 4) key_buffer_size 5) query_cache_size 6) record_buffer_size 7) read_rnd_buffer_size 8) sort_buffer_size 9) join_buffer_size 10) table_cache 11) max_heap_table_size 12) tmp_table_size

13) thread_cache_size 14) thread_concurrency 15) wait_timeout 一、优化概述 MySQL数据库是常见的两个瓶颈是CPU和I/O的瓶颈,CPU在饱和的时候一般发生在数据装入内存或从磁盘上读取数据时候。磁盘I/O瓶颈发生在装入数据远大于内存容量的时候,如果应用分布在网络上,那么查询量相当大的时候那么平瓶颈就会出现在网络上,我们可以用mpstat, iostat, sar和vmstat来查看系统的性能状态。 除了服务器硬件的性能瓶颈,对于MySQL系统本身,我们可以使用工具来优化数据库的性能,通常有三种:使用索引,使用EXPLAIN分析查询以及调整MySQL的内部配置。 二、查询与索引优化分析 在优化MySQL时,通常需要对数据库进行分析,常见的分析手段有慢查询日志,EXPLAIN 分析查询,profiling分析以及show命令查询系统状态及系统变量,通过定位分析性能的瓶颈,才能更好的优化数据库系统的性能。 1 性能瓶颈定位 Show命令 我们可以通过show命令查看MySQL状态及变量,找到系统的瓶颈: Mysql> show status ——显示状态信息(扩展show status like ‘XXX’) Mysql> show variables ——显示系统变量(扩展show variables like ‘XXX’) Mysql> show innodb status ——显示InnoDB存储引擎的状态 Mysql> show processlist ——查看当前SQL执行,包括执行状态、是否锁表等

oracle11g基于SQL的优化之索引优化篇

Oracle11g 基于SQL语句性能优化 通过索引对SQL进行优化 主讲人:马飞 所在部门:运维部

一、概述 本文所介绍的索引案例是在使用的是Oracle11g 11.2.0.4 数据库运行的。索引是使用最为普遍的一种优化SQL的方法,不同索引均有各自的优缺点。实际优化中需要综合考虑各种环境因素对运行慢的SQL进行优化。常见环境因素有:数据库表及索引的统计信息、列的柱状图,优化器的模式,表上是否有触发器,表上是否创建了物化视图日志,SQL语句是否使用提示符,当前会话的等待事件等。 Oracle数据库中索引可分为B-TREE索引、BitMap索引、全文索引三大类。按索引列的数量不同可分为,单列索引,多列索引。按列值是否唯一可分为唯一索引和非唯一性索引。 二、B-TREE索引 B-TREE索引常常用在OLTP数据库中,为了提高查询性,但同时一个表中索引数据多时会影响DML语句的性能,所以需要全面考虑增加索引后利弊。 2.1索引分类 主键索引、唯一键索引、非唯一键索引、多列组合索引。当表在创建主键时系统会自动为主键列或列的组合上创建唯一索引,主键索引性能最好。其它索引性能好坏取决于单列或多列的数据选择性,如果索引访问的数据小,性能相对较高,因为访问索引和表的块较少因而性能好。 2.2扫描方式 索引唯一扫描、索引范围扫描,全索引扫描,快速全索引扫描,索引跳跃扫描。 2.3上机实践 2.3.1 索引唯一扫描例子:

unique.txt 注意:由于唯一索引的列中可为空值。如果查询条件中有如下写法,则无法走索引扫描。因为b-tree索引中不存储空值。 (1)select * from tab where col is null (2)select * from tab where col is not null (3)select count(0) from tab; 其中(3)中的语句是否走索引取决于唯一索引的列上是否为非空,如果是非空,则会走“INDEX FAST FULL SCAN”快速索引扫描(采用并行索引扫描方式进行取读索引块,效率非常高)。 2.3.2 索引范围扫描例子 在非唯一性索引上的扫描通常都采用索引范围的扫描方式进行。 scan.txt scan2.txt 2.3.3 全索引扫描例子 全索引扫描指的是查询语句的所有列均在索引列中,同时需要访问全表的数据时使用。 indexfull.txt 2.3.4 快速全索引扫描例子 fast_fullscan.txt 2.3.5 索引跳跃扫描例子 skip.txt 2.4索引利弊 优点:当访问表中少量数据时可以提高查询的性能。

基于索引的SQL语句优化

基于索引的SQL语句优化 一、尽量避免非操作符的使用 通常情况下,为了对指定列建立特定的条件,需要在WHERE子句中使用诸如NOT、!=、<>、!<、!>等操作符,在索引列上使用这些非操作符,DBMS是不使用索引的,可以将查询语句转换为可以使用索引的查询。例: SELECT * FROM ORDERS WHERE ORDERDATE<>1997-l2 转化为:SELECT * FROM ORDERS WHERE ORDERDATE l998-l-l 这样DBMS就能利用索引字段ORDERDATE,大大提高查询效率。 二、避免困难的正规表达式 MATCHES和LIKE关键字支持通配符匹配,技术上叫正规表达式。但这种匹配特别耗费时间。 例如:SELECT * FROM STUDENT WHERE STUDENT_NUM LIKE “98_ _” 即使在STUDENT_NUM字段上建立了索引,在这种情况下也还是采用顺序扫描的方式。如果把语句改为SELECT * FROM STUDENT WHERE STUDENT_NUM >”98000”,在执行查询时就会利用索引来查询,显然会大大提高速度。如果一定要使用通配符也要避免通配符在搜索字段的首部出现,这种情况下DBMS的优化器不会使用索引[6]。 三、避免在索引列上使用NULL关键字 避免在索引中使用任何可以为空的列,ORACLE将无法使用该索引。即使索引有多列,只要这些列中有一列含有NULL,该列就会从索引中排除,也就是说如果某列存在空值,即使对该列建索引也不会提高性能[7]。 任何在WHERE子句中使用IS NULL或IS NOT NULL的语句,优化器是不允许使用索引的。 四、避免对查询的列使用数学运算 如果在查询列使用数学运算,则DBMS优化器先要处理数学运算也会影响查询效能。例如: (1)SELECT * FROM ORDERDETAILS WHERE QUANTITY*2<50 (2)SELECT * FROM ORDERDETAILS WHERE QUANTITY<25 虽然这两条查询的结果完全相同,但某些情况下第二个语句的执行效率远高于第一个,因此在查询前应将数学运算转化。

相关文档
最新文档