优化与索引
数据库优化方法与技巧

数据库优化方法与技巧数据库是现代信息系统中的核心组成部分,负责存储和管理数据,为应用程序提供高效的数据操作和查询功能。
然而,随着数据量和访问量的增加,数据库性能可能会受到限制,导致应用程序响应变慢甚至崩溃。
为了解决这个问题,数据库优化成为了必不可少的一环。
本文将介绍一些常用的数据库优化方法与技巧,从索引优化、查询优化、数据模型设计等方面来提高数据库的性能。
一、索引优化索引是提高数据库查询性能的重要手段。
在设计数据库时,通过对关键字段创建索引可以大大减少查询的时间复杂度,提高查询效率。
确定哪些字段需要创建索引,是一个需要仔细考虑的问题。
一般来说,可以根据以下几个原则进行索引优化:1.选择合适的索引类型:不同的数据库支持不同的索引类型,如B树索引、哈希索引、全文索引等。
根据需要选择最适合的索引类型可以提高查询效率。
2.避免过多索引:虽然索引可以加速查询,但是过多的索引也会带来额外的维护成本。
只选择关键字段创建索引,并在数据库设计中尽量避免冗余字段可以减少索引的数量。
3.使用组合索引:当需要同时根据多个字段进行查询时,可以考虑创建组合索引,将多个字段合并在一起作为索引,可以提高查询效率。
4.定期维护索引:随着数据库的更新,索引的性能可能会下降。
定期对索引进行维护,如重新构建索引、优化索引大小等,可以保持索引的高效性。
二、查询优化查询是数据库最常用的操作之一,优化查询性能对整个系统的响应速度有着重要的影响。
下面是一些常见的查询优化方法:1.减少查询结果集:只返回应用程序需要的数据可以减少查询的时间和数据传输的开销。
尽量使用SELECT语句指定需要的字段,避免使用SELECT * 来返回全部字段。
2.使用JOIN优化查询:当涉及到多个表的查询时,使用JOIN操作将多个查询合并为一个复杂查询可以减少数据库的访问次数,提高查询效率。
3.避免使用子查询:尽量避免使用子查询,特别是在大数据量的情况下,因为子查询会增加数据库的负载和查询的时间。
数据库系统中的查询优化与索引技术研究

数据库系统中的查询优化与索引技术研究导言在信息爆炸的时代,大量的数据需要有效地存储和管理。
数据库系统的发展为大规模数据管理提供了强有力的支持,而查询优化与索引技术则是数据库系统性能优化的核心。
本文将探讨数据库系统中的查询优化与索引技术,旨在深入理解其原理与应用。
一、查询优化的重要性1.1 查询优化对数据库性能的影响查询是数据库系统的核心操作之一,其性能直接影响到用户对数据库系统的使用体验。
当数据库中的数据量庞大时,执行一次查询可能需要耗费大量的时间和资源。
因此,通过优化查询过程,可以提高数据库系统的响应速度和处理能力,从而更好地支持各种应用需求。
1.2 查询优化的工作原理查询优化的主要目标是找到一种最优的查询执行计划,即最小化查询的时间和资源消耗。
在进行查询优化时,首先需要收集统计信息,包括表的大小、索引统计等。
其次,需要考虑查询的执行顺序以及使用哪些索引。
最后,通过代价估计和算法优化,选择出最佳的查询执行计划。
二、索引技术的研究与应用2.1 索引的作用与原理索引是数据库中存储数据的一种数据结构,通过在关键字段上建立索引,可以提高查询的效率。
常见的索引类型包括B树、B+树、Hash索引等。
索引的原理是利用数据结构的查询特性,使得查询过程能够快速定位目标数据,而不需要遍历整个数据集。
2.2 索引的设计与优化索引的设计是数据库系统中的一项重要工作,良好的索引设计可以明显提升查询性能。
在索引设计中,需要考虑索引的选择、索引字段的顺序等因素。
此外,在索引的使用与维护过程中,也需要进行一些优化措施,如定期重建索引、合理设置索引缓存等。
2.3 索引与数据库系统的集成索引技术在数据库系统中得到了广泛应用,几乎所有的数据库系统都支持索引功能。
在数据库系统中,索引与其他关键组件相互配合,实现高效的数据查询和更新。
索引与查询优化器、存储管理器等模块的集成,使得数据库系统能够更好地响应用户的查询需求。
三、查询优化与索引技术的研究进展3.1 查询优化与索引技术的挑战与难点查询优化与索引技术的研究面临着诸多挑战与难点。
使用MySQL进行全文索引和搜索优化

使用MySQL进行全文索引和搜索优化引言:在当今大数据时代,信息的快速检索和搜索成为一项非常重要的任务。
而全文索引是提高搜索效率的关键技术之一。
MySQL作为一种常用的关系型数据库,也提供了全文索引功能,可以帮助我们实现高效的全文搜索。
本文将介绍如何使用MySQL进行全文索引和搜索优化,以提升系统的性能和用户体验。
一、全文索引的基本概念和原理全文索引是一种将文本数据以特定的数据结构进行组织和管理,以支持关键字搜索的技术。
它可以快速地定位并返回包含搜索关键字的文档或记录。
全文索引常用于大型网站、论坛、博客等需要进行复杂搜索的应用场景。
全文索引的原理主要包括三个步骤:分词、建立倒排索引和搜索匹配。
1. 分词:将文本数据分割成一个个的词语,一般以空格、标点符号或其他分隔符号为界限。
分词可以使用自然语言处理工具,也可以使用MySQL内置的分词器。
2. 建立倒排索引:将分词之后的单词与其所在的文档或记录进行关联,形成倒排索引表。
倒排索引表记录了每个单词出现在哪个文档中,以及在该文档中的位置信息。
3. 搜索匹配:当进行全文搜索时,输入的关键字会与倒排索引进行匹配,找出与关键字相关的文档或记录。
二、MySQL全文索引的使用方法MySQL提供了全文索引的功能,并通过特定的语法和API使其易于使用。
下面以一个示例数据库为例,介绍MySQL全文索引的使用方法。
假设我们有一个名为"articles"的表,包含了文章的标题和内容字段。
首先,我们需要为"articles"表添加一个全文索引:```ALTER TABLE articles ADD FULLTEXT(title, content);```上述命令将在"title"和"content"字段上创建一个全文索引。
注意,只有使用MyISAM或InnoDB存储引擎的表才支持全文索引。
接下来,我们可以使用全文索引进行搜索。
数据库优化方法

数据库优化方法数据库是计算机系统中非常重要的一部分,它承载着大量的数据,为企业的决策提供了基础数据支持。
随着数据量的不断增大,数据库的性能问题也越来越突出。
为了提高数据库的性能,我们需要采取一些优化方法来提高数据库的响应速度和稳定性。
本文将介绍一些常见的数据库优化方法。
1. 索引优化索引是数据库优化的重要手段之一。
它可以大大提高查询速度,加快数据检索的效率。
在建立索引时,应该根据查询频率和数据量来选择合适的索引类型,以及优化索引的大小和深度。
同时,还需要定期对索引进行维护和优化,删除不必要的索引,重新构建或重建索引等操作,以保证索引的有效性和稳定性。
2. 数据库分区数据库分区是将数据库中的数据按照一定的规则分成多个部分,使得每个部分可以独立地进行管理和维护。
这样可以提高数据库的查询速度和数据的访问效率,同时还可以减少锁的竞争,提高并发性能。
在进行数据库分区时,需要考虑数据的访问频率、数据的大小和数据的类型等因素,以便选择合适的分区策略。
3. SQL优化SQL语句是数据库操作的核心,优化SQL语句可以提高数据库的性能。
在编写SQL语句时,应该尽量避免使用复杂的子查询和连接操作,优化查询条件,尽量减少检索数据的数量。
同时,还需要避免使用模糊查询和通配符查询等操作,以免影响查询速度和数据库的性能。
4. 数据库缓存数据库缓存是将经常访问的数据存储在内存中,以便快速访问。
这样可以减少数据库的读写操作,提高数据访问的速度和效率。
在进行数据库缓存时,需要考虑缓存的大小和缓存的更新策略,以保证缓存的有效性和稳定性。
5. 数据库备份和恢复数据库备份和恢复是数据库管理的重要任务之一。
它可以保证数据的安全性和完整性,防止数据丢失和损坏。
在进行数据库备份和恢复时,需要选择合适的备份策略和恢复策略,定期进行备份和恢复操作,以保证数据的安全性和可靠性。
6. 数据库监控和调优数据库监控和调优是保证数据库性能的关键。
它可以及时发现数据库的性能问题,进行调整和优化,提高数据库的响应速度和稳定性。
explain详解与索引优化最佳实践

explain详解与索引优化最佳实践索引是数据库中用来提高查询性能的一种数据结构。
它是数据库中对表中的数据进行快速查找的重要工具。
索引可以加速数据检索的速度,减少数据库的负载以及提高查询性能。
本文将详细介绍索引的概念、优化技巧以及最佳实践。
一、索引概述1.1索引的定义索引是一种特殊的数据库结构,它包含有一个或多个列的值和对应的记录位置的关联。
通过索引,可以很快地定位到包含特定值的记录,从而加快查询速度。
1.2索引的类型在数据库中,常见的索引类型有以下几种:-唯一索引:保证索引列的唯一性,可以加速查询速度。
-主键索引:是唯一索引的一种特殊形式,对于每个表只能有一个主键索引。
-聚集索引:按照索引键对表进行重新组织和排序,是表本身的排序方式。
-非聚集索引:使用一个单独的结构来存储索引,而不改变表的物理存储顺序。
二、索引优化技巧2.1确定索引字段在创建索引之前,需要确定哪些字段需要创建索引。
通常,以下类型的字段适合创建索引:-经常用于过滤和排序的字段。
-数据分布广泛的字段。
-表中经常被使用的字段。
2.2创建适当的索引根据查询的需求和表的结构,创建适当的索引。
以下是一些常见的索引创建技巧:-创建唯一索引,以提高查询和插入性能。
-对于经常进行范围查询的字段,可以创建组合索引。
-对于文本字段,可以使用全文索引以提高关键字搜索速度。
2.3避免创建过多的索引尽管索引可以加速查询速度,但是过多的索引会增加数据库的维护成本,并且可能导致性能下降。
因此,需要避免创建过多的索引。
在创建索引之前,应该先评估查询需求和数据量,并根据实际情况进行选择。
2.4定期更新索引统计信息索引统计信息用于优化查询计划的生成。
如果索引统计信息过时或不准确,将会导致查询性能下降。
因此,需要定期更新索引统计信息以保持其准确性。
2.5考虑使用索引覆盖索引覆盖是一种技巧,通过创建包含查询所需字段的复合索引,可以避免对原始数据的访问,从而提高查询性能。
如何优化Windows系统的文件搜索和索引速度

如何优化Windows系统的文件搜索和索引速度Windows系统作为广泛使用的操作系统之一,文件搜索和索引速度的优化对于提高系统的工作效率和用户体验至关重要。
本文将介绍一些优化Windows系统文件搜索和索引速度的方法,帮助用户更高效地管理和查找文件。
一、清理磁盘空间1.删除临时文件:Windows系统会生成大量的临时文件,占用磁盘空间并拖慢搜索速度。
通过定期清理临时文件夹(%temp%)可以释放磁盘空间,提高系统搜索效率。
2.卸载不必要的程序:卸载不再使用的软件可以减少占用的磁盘空间和系统资源,降低搜索和索引的负担。
3.清理回收站:回收站中的文件虽然已经被删除,但仍然占用磁盘空间,可以定期清空回收站来释放空间和提高搜索速度。
二、优化文件索引设置1.选择适当的索引位置:Windows系统默认将索引保存在系统驱动器(通常是C盘)上,可以根据个人需求将索引位置移到其他磁盘,以减少系统盘的负担,提高索引和搜索速度。
2.选择需要索引的文件类型:在索引选项中可以指定需要进行索引的文件类型,只选择必要的文件类型可以缩小索引范围,提高索引速度。
3.排除不需要索引的文件夹:对于某些不常使用或者不需要快速搜索的文件夹,可以在索引选项中进行排除设置,减少不必要的索引任务,加快索引速度。
三、调整文件搜索选项1.利用快速访问栏:Windows 10系统提供了快速访问功能,可以将常用的文件夹和文件固定在快速访问栏中,方便快速查找和打开。
2.使用关键词进行搜索:在文件资源管理器中直接使用关键词进行搜索,避免过于依赖索引,提高搜索效率。
3.使用文件名通配符:使用文件名通配符(如*.doc)进行搜索可以缩小搜索范围,减少匹配的文件数量,加快搜索速度。
四、禁用不必要的Windows搜索功能1.禁用Windows索引服务:对于不常使用系统搜索功能的用户,可以在服务管理器中禁用Windows索引服务,以减轻系统负担。
2.禁用网络文件搜索:若不需要在网络文件中进行搜索,可以禁用相关功能,提高本地文件搜索速度。
Hadoop中的数据索引和查询优化技术解析

Hadoop中的数据索引和查询优化技术解析Hadoop是一种开源的分布式计算框架,被广泛应用于大数据处理和分析。
在Hadoop中,数据索引和查询优化是关键的技术,它们可以提高数据的访问效率和查询性能。
本文将对Hadoop中的数据索引和查询优化技术进行解析。
一、数据索引技术数据索引是一种用于加速数据访问的技术,它通过建立索引结构来提供快速的数据定位和检索能力。
在Hadoop中,常用的数据索引技术包括B树索引、倒排索引和压缩索引。
1. B树索引B树是一种多路平衡查找树,它可以在有序数据上进行高效的查找操作。
在Hadoop中,B树索引常被用于加速数据的范围查询。
通过将数据按照某个属性进行排序,并构建B树索引,可以使得范围查询的性能得到显著提升。
2. 倒排索引倒排索引是一种常用的文本检索技术,它将文档中的每个单词映射到包含该单词的文档列表中。
在Hadoop中,倒排索引常被用于加速文本数据的关键词搜索。
通过构建倒排索引,可以快速定位包含指定关键词的文档。
3. 压缩索引压缩索引是一种将索引数据进行压缩存储的技术,它可以减小索引的存储空间,并提高索引的读取性能。
在Hadoop中,由于数据量庞大,索引的存储和读取成本往往较高。
通过采用压缩索引技术,可以在一定程度上减小存储空间,提高索引的读取效率。
二、查询优化技术查询优化是指通过改变查询的执行方式,使得查询的执行效率得到提升的一种技术。
在Hadoop中,常用的查询优化技术包括查询重写、查询优化器和查询计划生成器。
1. 查询重写查询重写是指对用户提交的查询进行改写,以使得查询的执行效率得到提升。
在Hadoop中,查询重写常用于优化复杂查询和多表关联查询。
通过改变查询的语法结构或者调整查询的执行顺序,可以减少查询的执行时间和资源消耗。
2. 查询优化器查询优化器是一种自动化工具,用于选择最优的查询执行计划。
在Hadoop中,查询优化器可以根据查询的特点和数据的分布情况,选择最适合的查询执行计划。
数据库索引的维护与优化技巧

数据库索引的维护与优化技巧数据库索引是提高数据库查询性能和数据检索效率的重要手段。
然而,在大量数据的情况下,使用不当的索引或索引的维护不完善会导致性能下降甚至崩溃。
本文将介绍一些数据库索引的维护和优化技巧,以帮助开发人员有效提升数据库的性能。
1.选择合适的索引在创建索引时,需要选择适合的字段作为索引列。
通常情况下,那些经常用于查询条件的字段应该作为索引列。
例如,在用户表中,根据用户名进行查询的频率很高,那么可以考虑为用户名列创建索引。
然而,过多的索引也会降低写操作的性能,因此需要权衡和选择。
2.避免冗余索引冗余索引是指多个索引覆盖相同的查询。
在实际应用中,由于人为疏忽或者维护失误,可能会创建相似的索引。
这不仅浪费了存储空间,还降低了修改数据时的性能。
因此,在设计数据库时,需要避免创建冗余索引,可以通过审查现有索引来识别和删除冗余索引。
3.使用组合索引组合索引是指由多个列组成的索引。
当多个列常常同时出现在查询条件中时,使用组合索引可以提高查询效率。
例如,在订单表中,同时根据订单日期和订单状态进行查询,可以为这两个字段创建组合索引。
组合索引更适用于查询频繁的列组合,可以减少索引的个数和占用的存储空间。
4.避免过度索引虽然索引可以提高查询性能,但是过度使用索引会降低写操作的性能。
因此,需要谨慎选择索引,并考虑索引对写操作的影响。
不需要频繁更新或插入的列可以不创建索引,以减少索引的维护和空间开销。
5.及时更新和重新组织索引随着数据的增长和修改,索引的结构和数据会变得不连续。
这可能导致查询效率下降。
因此,定期检查和更新索引是保持数据库性能的重要步骤之一。
可以通过数据库提供的优化工具或脚本来重新组织索引,以减少索引碎片和提高查询效率。
6.注意索引与数据的一致性当数据库中的数据发生改变时,索引也需要相应的更新。
如果不及时更新索引,可能会导致查询结果不一致或索引失效。
因此,在进行数据的插入、更新和删除操作时,确保及时更新相关的索引,保持数据的一致性和正确性。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
@对表的访问1、全表扫描1、对表所有的块,进行访问,采用多块读的方式2、设置多块读的参数SQL> show parameter db_file_multiblockNAMETYPE 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%以上的数据过滤掉,我们就应该考虑这个过滤的价值,也就是cost2、走索引不使用多块读1、成本计算:访问索引的成本+索引访问表的成本访问索引的成本:索引树的高度+叶子节点的块数索引访问表的成本:行数*集群因子/总行数2、集群因子:最小值就是表的块数最大值就是表的行数集群因子高带来的问题:1、计算走索引的时候的成本高2、额外的占用过多的buffer3、额外的增加物理io3、取得数据量一般<5%~20%的话我们建议走索引4、Oracle在计算成本的时候是假设所有的数据都在磁盘中,这样的话计算的成本都有物理读,而实际的生产中我们经常读取的数据,大部分都缓存在内存中5、全表扫描在oltp中肯定会产生额外的一些物理读,因此一般不要全表扫描表整理:表不存在碎片的问题,表时间长了会有一个集群因子很高的问题,有些索引是一个表的主索引,时间长了可以按照主索引对这个表重新生成一下,按照这个主索引排下序,这样的话表的集群因子又会降下来了select d.clustering_factor from dba_indexes d where d.table_name='T1'and owner='SYS '; //查看表的集群因子大小select t.num_rows,t.blocks from dba_tables t where t.table_name='T1'and owner='SYS' ; //查看表的行数和块数SQL> select * from t1 where object_id=10;Execution Plan----------------------------------------------------------Plan hash value: 3617692013--------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | --------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 8 | 1416 | 155 (2)| 00:00:02 ||* 1 | TABLE ACCESS FULL| T1 | 8 | 1416 | 155 (2)| 00:00:02 |--------------------------------------------------------------------------Predicate Information (identified by operation id):---------------------------------------------------1 - filter("OBJECT_ID"=10)Note------ dynamic sampling used for this statementStatistics----------------------------------------------------------5 recursive calls //递归sql 产生系统级别的select0 db block gets762 consistent gets //内存读0 physical reads //物理读0 redo size1401 bytes sent via SQL*Net to client // 服务器给客户端发的字节492 bytes received via SQL*Net from client //接收的字节2 SQL*Net roundtrips to/from client //客户端和服务器的响应0 sorts (memory) //内存排序0 sorts (disk)1 rows processed //实际返回一行1、select*from dba_indexes d where d.index_name like'I_T1%'and owner='SYS';blevel:是索引的树的高度,一般在5以下distinct_keys:唯一值得数量avg_leaf_blocks_per_key:平均块中的叶子块avg_data_blocks_per_key:平均每个块中的数据块在这里面有一列是distinct_keys和num_rows 我们希望distinct_keys很高num_rows/distinct_keys若是很高那么就会取出很多行,所以这样是不好的,我们希望的是索引的值很高接近这个num的值索引:1、选择性希望distinct_keys/num_rows的值大一些选择性高说明where条件取出的数值少2、集群因子cluster_factor 取决于索引访问表的值看索引好不好主要是上面的两个值2、关于索引的几个参数SQL> show parameter indNAME TYPE VALUE------------------------------------ ----------- ------------------------------optimizer_index_caching integer 0 //假设访问索引的时候,索引所有的块都不在内存中,也就是将访问索引的部分也计算其内存读,但是如果说设置成100的时候他会忽略访问索引发生的物理IO,不管是不是在内存中。
optimizer_index_cost_adj integer 100 //生产中一般改成50 ,设置成50表示,在计算成本的时候,走索引的成本*50%这个时候如果是小于全表扫描的成本那么这个时候就会选择走索引skip_unusable_indexes boolean TRUEuse_indirect_data_buffers boolean FALSE3、为什么使用索引看一个SQL语句的执行计划:SQL> set autotrace traceSQL> select * from t1 where object_id=10;Execution Plan----------------------------------------------------------Plan hash value: 852682354----------------------------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |----------------------------------------------------------------------------------------------| 0 | SELECTSTATEMENT | | 1| 93 | 2 (0)| 00:00:01 || 1 | TABLE ACCESS BY INDEX ROWID| T1 | 1 | 93 | 2 (0)| 00:00:01 ||* 2 | INDEX RANGE SCAN | I_T1_OBJECT_ID | 1 | | 1 (0)| 00:00:01 |----------------------------------------------------------------------------------------------//通过上面的可以看出先访问索引,然后通过索引去访问这个表Predicate Information (identified by operation id):---------------------------------------------------2 - access("OBJECT_ID"=10)//access就是直接去找OBJECT_ID=10所对应的值,而不是全部扫描完了去找,而是有目的的去找Statistics----------------------------------------------------------0 recursive calls0 db block gets4 consistent gets0 physical reads0 redo size1401 bytes sent via SQL*Net to client492 bytes received via SQL*Net from client2 SQL*Net roundtrips to/from client0 sorts (memory)0 sorts (disk)1 rows processedaccess:直接本主题去找,而不是全部访问一遍,也就是说根据object_id=10走索引直接找到数据往往意味着走索引,直接读取有用的数据,没有读取过多的数据很多时候会将filter改变成access,减少内存读的时候,自然就减少了物理读如何看一个sql的执行优劣1、内存度的数量主要是看的内存高不高2、物理读的话,第一次执行,物理读高,自然时间就长3、不要看执行时间最好去除解析,也就是去除递归sql以后的一些内存读清理buffer cache走索引好处:1、通过走索引,可以避免全表扫描,减少内存读和物理读where条件中2、减少排序SQL> select * from t1 order by object_id;50829 rows selected.Execution Plan----------------------------------------------------------Plan hash value: 2148421099-----------------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |-----------------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 50829| 4616K| | 1249 (1) | 00:00:15 || 1 | SORT ORDER BY | | 50829| 4616K| 6264K | 1249 (1) | 00:00:15 || 2 | TABLE ACCESS FULL | T1 | 50829| 4616K| | 156 (2) | 00:00:02 |-----------------------------------------------------------------------------------Statistics----------------------------------------------------------1 recursive calls0 db block gets702 consistent gets0 physical reads0 redo size2547630 bytes sent via SQL*Net to client37760 bytes received via SQL*Net from client3390 SQL*Net roundtrips to/from client1 sorts (memory)0 sorts (disk)50829 rows processed通过走索引减少排序select/*+index(t t.i_t1_object_id)*/*from t1 t where object_id=object_id order by object_id;访问表的时候,如果出现了临时段的排序,也就是磁盘排序,严重的影响了性能,那么可以采取上面的措施,可以走索引,走哪个索引?走排序列上的索引3、索引可以引导我们走嵌套循环4、索引减少对表的访问要访问的列都在索引上那么就直接访问索引,不走表select /*+index(t t.i_t1_object_id*/ object_id from t1 where object_id=object_id;5、走索引的情况:1、where子句中使用到了索引列2、没有where子句,但是也可能使用到索引查询索引列的MIN或者是MAXSQL> select min(object_id) from t1;对索引列执行countSQL> select count(object_id) from t1;SQL> select count(*) from t1; //不走索引如果是要走索引那么可以在列上加上非空区别:index fast full scan:多块读取出来的数据是无序的index full scan:通过索引定位到一个表的第一行,一个块一个块的读,加入说是100个块这个时候就会发生100次物理IO也就是单块顺序读,取出来的顺序是有序的5、访问索引经常访问的视图select * from dba_indexes where table_name='T1';select * from dba_ind_columns d where d.table_name ='T1'select * from dba_ind_statistics e where e.table_name='T1;复合索引 (很重要)create index i_t1_id_name on t1(object_id,object_name); //给表t1创建一个索引select * from dba_ind_columns d where d.table_name='T1'; //查看t1表上的列的索引exec dbms_stats.gather_table_stats('SYS','T1'); //收集统计信息select * from dba_ind_statistics e where e.table_name='T1'; //查看一下上面收集的统计信息强制走现在的新索引select /*+index(t t.I_T1_ID_NAME) */ * from t1 t where object_id=100 and object_name='T1';必须有前导列出现在where条件中,才有可能走索引,比如说上面的复合索引的前导列是object_id,这个时候若是执行select /*+index(t t.I_T1_ID_NAME)*/ * from t1 t where object_name='I_IND1';是不走索引的,这是一般情况,也就是在一个表中有两列上存在索引这个时候,如果说上面的and改成or这个时候也不会走索引#不走索引的一些情况1、<>2、orselect*from t3 where object_id=100and object_name like'TAB$'or object_name like'COL$';//这样是不走索引的select*from t3 where object_id=100and(object_name like 'TAB$'or object_name like'COL$');//这样是可以的3、is not null、is null 也不走索引select*from t3 where object_id is not null4、集群因子很高、取的数据量相对大,也可能不走索引,这个可以加hints强制走索引5、列上加了函数,也不走索引,建立基于函数的索引,函数只能是系统自带函数,生产自己建立的函数不能建立基于函数的索引create index i_t3_id_fun ont3(to_char(object_id)); //基于函数建立索引select*from t3 where to_char(object_id)='100' //这个时候就能够走索引6、||也不走索引,解决的方式如下select*from t3 where to_char(object_id)='100'and to_char (object_id)||'A'='100A'#不要随意的建立复合索引1、索引大,会带来额外的物理io2、对dml会有影响#跳跃式索引扫描在两个列上建立索引,在一个列上的值很少,另一个列上的值很多,这个时候就会跳跃式扫描假如是object_id只有3个值,执行select * from t1 where object_name='T1'的时候Oracle会自动转换成select * from t1 where object_id=1 and object_name='T1';union allselect * from t1 where object_id=2 and object_name='T1';union allselect * from t1 where object_id=3 and object_name='T1';#建立复合索引的目的和判断标准复合索引建立完成以后,相对只在前导列上建立索引1、distinct keys有明显提高2、索引的块数不要增加太多,也就是索引不要太大通过这种方式,可以大幅的对系统的复合索引进行修改但是有一种情况,需要注意select object_name from t1 where object_name='T1' // name 这一个列上有复合索引,这个时候就会走复合索引,但是如果说在name列上没有复合索引,那么就不会走索引,如果说这个表很大,那么这个时候就会进行一个大表的全表扫描,造成效果比较差看执行计划:实际上没有执行SQL> explain plan for select * from t1 where object_id=101;Explained.SQL> select * from table(dbms_xplan.display);可以通过rowid去访问一个表,但是实际的生产中是不会这样的SQL> select object_id,rowid from t1 where rownum=1;OBJECT_ID ROWID---------- ------------------20 AAANjrAABAAAOAiAAASQL> set autotrace traceSQL> select * from t1 where rowid='AAANjrAABAAAOAiAAA';Execution Plan----------------------------------------------------------Plan hash value: 487051824-----------------------------------------------------------------------------------| Id |Operation | Name | Rows | Bytes | Cost (%CPU)| Time |//rows是一个估算值,不准//cost是一个累积值,在0的时候花费的是0是估算值主要是包括cpu+IO 在这cpu消耗是0 //time也是估算值,也是累计值-----------------------------------------------------------------------------------| 0 | SELECTSTATEMENT | | 1 |93 | 1 (0) | 00:00:01 || 1 | TABLE ACCESS BY USER ROWID|T1 | 1 | 93 | 1 (0) | 00:00:01 |-----------------------------------------------------------------------------------Statistics----------------------------------------------------------0 recursive calls0 db block gets1 consistent gets0 physical reads0 redo size1397 bytes sent via SQL*Net to client492 bytes received via SQL*Net from client2 SQL*Net roundtrips to/from client0 sorts (memory)0 sorts (disk)1 rows processed##总结为什么走索引1、从表中取少量的数据,尽量走索引<5%~20%2、表中存放的数据有新旧之说,生产上不会访问旧的数据,一直在访问新的数据新的数据一般都在buffer中,走索引,一般不会发生大量的物理io,即使数据量大到20%,而且集群因子很高,走索引效果也很好,不要走全表扫描hash join往往会让我们走全表扫描##索引的特点1、索引很小往往被缓存到内存中去,所以索引常驻内存,这个时候访问索引的成本,物理io很低常用的视图:select*from v$segment_statistics where object_name='T1';statistic_name这一列中值得含义statistic_name这个是一个累计信息--logical reads 若是很高,可能说明索引建立的有问题--若是一个对象buffer busy waits很高说明这个对象是一个热对象--gc buffer busy是指在rac中有一个块在节点1上这个时候有进程在访问这个块,这个时候另一个节点也想访问这个块,这个时候就会造成gc buffer busy当这个值很高的时候说明这个对象也是热对象--db block changes 数据块被改变过就加1,如果说这个值很高,那么就说明这个块别改变很频繁--physical reads如果说这个这个索引的物理读很高,那么说明这个索引建立的非常大,可能是复合索引,dbwrite完成的--physical reads direct是一个server process直接从磁盘中将数据读到PGA中去,不经过buffer,server process完成的--gc cr blocks received表示在远端传过来的量,如果说这个值比较大,说明对这个段进行大量的读取,需要在远端进行数据的读取,将数据块构造出来--gc current blocks received--ITL waits产生这个说明存在了事物槽的争用,可以增加这个段的pct free--segment scans代表对一个表的全表扫描的次数,若是高则说明是全表扫描很高一个对象改变量很大的时候我们希望这个块常驻一个节点,不要在两个节点之间传来传去2、排序、树,可以快速定位数据#索引的选择性和集群因子1、索引的选择性越高索引越好,最好是接近表的行数2、集群因子,越低索引越好,最好是接近表的块数#柱状图1、什么时候需要柱状图一个列上有where条件这个列上有严重的数据倾斜2、柱状图是什么东西可以描述这个列上的一个数据倾斜的情况,柱状图来存储这个列上的数据的情况1、统计信息2、需要额外收集3、反映这个列上的数据倾斜情况3、柱状图的收集方法添加柱状图后,发生数据倾斜那部分是不走索引的,没有发生数据倾斜的部分还是要走索引的--收集柱状图begindbms_stats.gather_table_stats(ownname =>'SYS',tabname =>'T3',method_opt =>'for col umns size auto object_id');end;--可以查看到这个表的一些情况,尤其是列值,柱状图select*from dba_tab_col_statistics d where d.table_name='T3'and d.owner='SYS'--能够看到列上面的数据倾斜的情况select*from dba_tab_cols e where e.table_name='T3'and e.owner='SYS';--查看柱状图的信息select*from dba_histograms f where f.owner='SYS'and f.table_name='T3';--endpoint_number是指占的桶的数量4、关注一个参数cursor_sharing有3个值:EXACT:对于一个select语句:select …… from t1 where object_id=100;oracle对这个原本的select的语句做hash,然后去library cache中去寻找执行计划cursor有,soft parse无,hard parseFORCE:直接将上面的select语句替换成select …… from t1 where object_id=:1;然后进行hash,然后去library cache中去寻找执行计划cursor有,soft parse无,hard parseSIMILAR:如果where列上存在柱状图,说明有数据倾斜,那么不使用绑定变量,同exact 如果说where列上不存在数据倾斜,使用替换绑定变量,同force#索引类型1、B树索引2、位图索引 //用在数据仓库里面的3、索引组织表IOT4、基于函数的索引5、分区索引(本地索引、全局索引)OLTP数据库中用的最多的是B树索引&B树索引(普通索引,要求列的选择性很高)单列索引组合索引&位图索引(在OLTP中基本上不会采用)可以提取大量的数据,25%1、列的选择性低(列上唯一值得数量)必须很低2、create bitmap index3、DML并发性非常差特别是对于insert和delete4、表如果是只读表,而且存在大批量取数据的情况】可以考虑位图索引&IOT索引组织表可以考虑使用1、在一个表中取相对大量的数据2、范围取数据,between and没有cluster factor的概念,省去了通过索引从表中取数据的这个步骤3、如果不是按照主键取数据,就比较麻烦需要建立二级索引性能相对较差4、对于DML成本较高对主键的update较少数据的插入删除插入新数据,删除旧数据新旧按照主键5、对于旧数据抽走的情况,不太适合配合分区,分区一旦被抽空,直接drop分区即可&基于函数的索引尽量修改SQL,让where后面的列上面不要有函数,尽量将函数放在列值上面,不要放在列上&分区索引解决的问题是索引大的问题如果能够实现索引分区消除,效果最好对于分区索引的理解对于表是否分区,以及怎么分区,可以认为没有关系索引分区可以实现访问一个小的索引,也可能是访问多个小的索引,有一些索引分区被消除索引没有分区访问一个大的索引大索引和小索引的区别:树的高度不一样,索引的高度一般<=6树枝和树根都在内存里面索引分区基本上没有意义1、全局分区索引(效果很差)表分区和索引分区没有任何关系表的分区的改变,会导致全局分区索引失效alter table …… update global in dex2、局部分区索引(索引的分区和表的分区完全一致),也可以叫local前缀:表的分区列出现在索引中,而且是第一列非前缀:表的分区列没有出现在索引中,或者出现在索引的非第一个列中3、我们可以考虑索引分区情况1、这个索引的物理io很高可能是内存空间有限,系统数据量很大2、索引访问很频繁3、对索引进行分区,主要是分散物理io4、局部分区索引可以降低分区表的索引维护成本#解决物理io的思路1、尽量内存读,不要物理读2、将物理读分散#降低io有效的办法:1、索引2、cluster factor3、分区表、索引4、IOT(局限性大)5、位图索引、聚簇表(局限性大)6、物化视图上面的集中办法组合使用##补充知识1、有意识建立索引2、有意识建立合适的索引索引的建立1、开发人员10W行以上的表需要建立索引一个表上尽量不要超过6个索引表的索引的建立:访问这个表的时候,总是通过哪些列作为过滤条件,而且这个过滤条件可以过滤掉大部分数据OLTP1、过滤条件访问表2、过滤掉绝大多数数据2、针对sql看执行计划,filter条件,如果filter过滤大量的数据,但是没有出现在access里面,可以针对这个SQL增加索引这个索引解决了这个SQL问题,可能会导致其他SQL性能差尽量避免在列上建立重复索引如果建立这个索引以后,这个SQL的性能得到大幅提升,本质提升,这个SQL目前已经影响系统性能了,这个时候会考虑针对SQL建立索引在一个SQL上建立索引后,这个SQL的性能比以前有提高,但是不是很明显,而且这个SQL目前运行的还行,那么在这个SQL上建立索引会导致其他SQL的问题3、建立索引要统筹规划,统一建立索引,统一对系统进行调优最好做好预案col_usage$dba_tab_cols4、在表的外键上建立索引索引的三大功能:1、减少全表扫描,也就是减少物理io,通过索引在表中取数据2、可以省略sort,通过索引访问表的时候本身就是一行一行有序的取得,因为排序可能会导致性能很差,导致磁盘排序3、要访问的列如果说在索引中并且索引效率高是最好的索引的坏处:1、索引多了对增删改,特别是update影响比较严重,一个表上的索引最好不要超过6个2、建索引的时候,要对这个表进行锁表,对这个表进行全表扫描,这样的话可能需要10分钟、20分钟等,那么生产上这个表就会被锁住,极端情况下会导致数据库hang住,还有可能造成磁盘排序,产生磁盘io,极端情况下会导致数据库hang住3、在数据库上建了一个索引,这个索引可能将这个sql的性能问题解决了,但是可能导致其他的sql 也走这个索引,导致数据库的性能突然降下来所以在生产上建索引的时候要谨慎,通盘考虑,平时还要注意,在建索引的时候,也就是rebuild 的时候加上online,也就是在原来的基础上建立索引,这样的话避免了排序。