Maison > Article > base de données > De quels index Oracle dispose-t-il ?
Les types d'index d'Oracle incluent : l'index non unique, l'index unique, l'index bitmap, l'index de partition de préfixe local, l'index de partition local sans préfixe, l'index de partition de préfixe global, l'index de partition de hachage et l'index basé sur les fonctions. L'index doit être créé après l'insertion des données dans la table. Un index unique peut être créé avec l'instruction "create unique index".
L'environnement d'exploitation de ce tutoriel : système Windows 7, version Oracle 11g, ordinateur Dell G3.
Qu'est-ce qu'un indice ?
L'index se compose du nœud racine, du nœud branche et du nœud feuille. Le bloc d'index de niveau supérieur contient les données d'index du nœud inférieur. -bloc d'index de niveau, et le nœud feuille contient les données d'index et détermine la position réelle de la ligne.
Description de l'index
1) L'index est l'un des objets de base de données, utilisé pour accélérer la récupération des données, similaire à l'index d'un livre. L'indexation dans une base de données peut réduire la quantité de données qu'un programme de base de données doit lire lors de l'interrogation des résultats, de la même manière que dans les livres, nous pouvons utiliser les index pour trouver les informations souhaitées sans avoir à lire le livre en entier.
2) L'index est un objet facultatif construit sur la table ; la clé pour indexer est de remplacer la méthode de récupération par défaut de l'analyse complète de la table par un ensemble de clés d'index triées, améliorant ainsi l'efficacité de la récupération
3) L'index est logique et physique, cela n'a rien à voir avec les tables et données associées. Lors de la création ou de la suppression d'un index, cela n'affectera pas la table de base
4) Une fois l'index établi, lors de l'exécution d'opérations DML sur la table (telles que l'insertion, la modification) , ou suppression) Lors des opérations associées), Oracle gérera automatiquement l'index et la suppression de l'index n'affectera pas la table
5) L'index est transparent pour l'utilisateur, qu'il y ait ou non un index sur la table, son utilisation. de l'instruction SQL reste inchangée.
6) Création Oracle Lorsque la clé primaire est utilisée, un index sera automatiquement créé sur la colonne
Le but de l'utilisation de l'index :
Quand utiliser les index :
Types d'index
Directives pour la gestion des index
import
Enfin, l'indexation est plus efficace import
工具插入或装载数据后,建立索引比较有效;索引正确的表和列
为性能而安排索引列
dx_groupid_serv_id(groupid,serv_id)
,在where
条件中使用groupid
或groupid,serv_id
,查询将使用索引,若仅用到serv_id
Indexez les bonnes tables et colonnes
Récupérez souvent 40% des lignes d'une grande table triée ou 7% d'une table non triée, il est recommandé de construire un index
Organisez les colonnes d'index pour les performances
dx_groupid_serv_id(groupid,serv_id)
, utilisez groupid
ou groupid dans <code>where
condition, serv_id, la requête utilisera l'index Si seul le champ serv_id
est utilisé, l'index sera invalide ;
🎜Une table peut avoir des centaines d'index (feriez-vous cela ?), mais pour des insertions et des mises à jour fréquentes de la table, plus le processeur du système a d'index, I/ O Plus la charge est lourde 🎜🎜🎜🎜 Il est recommandé que chaque table ne comporte pas plus de 5 index. 🎜🎜🎜🎜🎜Supprimer les index qui ne sont plus nécessaires🎜🎜🎜🎜🎜Index invalides, principalement en raison de l'utilisation d'index basés sur des fonctions ou d'index bitmap au lieu d'index arborescents B* 🎜🎜🎜🎜Les requêtes dans les applications ne sont pas valides ; Utilisez index ; 🎜🎜🎜🎜Vous devez supprimer l'index avant de reconstruire l'index. Si vous utilisez alter index...rebuild pour reconstruire l'index, vous n'avez pas besoin de supprimer l'index. 🎜🎜🎜🎜🎜Indexer l'utilisation de l'espace des blocs de données🎜🎜
La création d'index en parallèle peut être utilisée pour les grandes tables. Lors de la création d'index en parallèle, les paramètres de stockage sont utilisés séparément par chaque processus du serveur de requêtes, par exemple :
initial est 1M
, le parallélisme est 8
, alors au moins 8M
sera consommé lors de la création de l'index initial
为1M
,并行度为8
,则创建索引期间至少要消耗8M
空间;考虑用nologging
创建索引
怎样建立最佳索引?
明确地创建索引
create index index_name on table_name(field_name) tablespace tablespace_name pctfree 5 initrans 2 maxtrans 255 storage ( minextents 1 maxextents 16382 pctincrease 0 );
创建基于函数的索引:
常用与UPPER、LOWER、TO_CHAR(date)
等函数分类上,例:
create index idx_func on emp (UPPER(ename)) tablespace tablespace_name;
创建位图索引:
对基数较小,且基数相对稳定的列建立索引时,首先应该考虑位图索引,例:
create bitmap index idx_bitm on class (classno) tablespace tablespace_name;
明确地创建唯一索引
可以用create unique index
语句来创建唯一索引,例:
create unique index dept_unique_idx on dept(dept_no) tablespace idx_1;
创建与约束相关的索引
可以用using index
字句,为与unique
和primary key
约束相关的字段创建索引,例如:
alter table table_name add constraint PK_primary_keyname primary key (field_name) using index tablespace tablespace_name;
如何创建局部分区索引
Create Index TG_CDR04_SERV_ID_IDX On TG_CDR04(SERV_ID) Pctfree 5 Tablespace TBS_AK01_IDX Storage ( MaxExtents 32768 PctIncrease 0 FreeLists 1 FreeList Groups 1 ) local /
如何创建范围分区的全局索引
基础表可以是全局表和分区表。
create index idx_start_date on tg_cdr01(start_date) global partition by range(start_date) (partition p01_idx vlaues less than (‘0106’) partition p01_idx vlaues less than (‘0111’) … partition p01_idx vlaues less than (‘0401’ )) /
重建现存的索引
重建现存的索引的当前时刻不会影响查询;
重建索引可以删除额外的数据块;
提高索引查询效率;
alter index idx_name rebuild nologging;
对于分区索引:
alter index idx_name rebuild partition partiton_name nologging;
要删除索引的原因
<br> drop index idx_name; <br> drop index idx_name drop partition partition_name; <br>
建立索引的代价
基础表维护时,系统要同时维护索引,不合理的索引将严重影响系统资源,主要表现在CPU和I/O上;
插入、更新、删除数据产生大量db file sequential read
锁等待;
一个表中有几百万条数据,对某个字段加了索引,但是查询时性能并没有什么提高,这主要可能是oracle
的索引限制造成的。
oracle
的索引有一些索引限制,在这些索引限制发生的情况下,即使已经加了索引,oracle
还是会执行一次全表扫描,查询的性能不会比不加索引有所提高,反而可能由于数据库维护索引的系统开销造成性能更差。
扩展知识:常见的索引限制问题
1、使用不等于操作符(a8093152e673feb7aba1828c43532094, !=)
下面这种情况,即使在列dept_id
有一个索引,查询语句仍然执行一次全表扫描
select * from dept where staff_num <> 1000;
但是开发中的确需要这样的查询,难道没有解决问题的办法了吗?
有!
通过把用 or 语法替代不等号进行查询,就可以使用索引,以避免全表扫描:上面的语句改成下面这样的,就可以使用索引了。
select * from dept shere staff_num < 1000 or dept_id > 1000;
2、使用 is null 或 is not null
使用 is null
或is nuo null
也会限制索引的使用,因为数据库并没有定义null
值。如果被索引的列中有很多null,就不会使用这个索引(除非索引是一个位图索引,关于位图索引,会在以后的blog文章里做详细解释)。在sql语句中使用null
会造成很多麻烦。
解决这个问题的办法就是:建表时把需要索引的列定义为非空(not null
)
3、使用函数
如果没有使用基于函数的索引,那么where
nologging
Créer un index 🎜🎜🎜🎜 Vous pouvez utiliser nologging pour réduire les journaux de rétablissement lors de la création d'index pour de grandes tables 🎜🎜 Économisez de l'espace dans les fichiers de journalisation 🎜🎜 Réduisez le temps de création des index ; lors de la création de grands index en parallèle . 🎜🎜🎜Comment créer le meilleur index ?🎜🎜Créer des index explicitement🎜select * from staff where trunc(birthdate) = '01-MAY-82';🎜Créer des index basés sur des fonctions :🎜🎜 Couramment utilisé avec
UPPER, LOWER, TO_CHAR(date)
et d'autres fonctions, par exemple : 🎜select * from staff where birthdate < (to_date('01-MAY-82') + 0.9999);🎜Création d'un index bitmap :🎜🎜Lors de la création d'un index pour une colonne avec une petite base et une base relativement stable base, les premiers index Bitmap doivent être pris en compte, par exemple : 🎜
select * from dept where dept_id = 900198;🎜 Créer explicitement un index unique 🎜🎜 Vous pouvez utiliser l'instruction
create unique index
pour créer un index unique, par exemple : 🎜select * from dept where dept_id = '900198';🎜 Create un index lié à une contrainte 🎜🎜 Vous pouvez utiliser la clause
using index
pour créer un index pour les champs liés à l'unique
et à la clé primaire
des contraintes, par exemple : 🎜Column1 like ‘aaa%’ 是可以的 Column1 like ‘%aaa%’用不到🎜Comment créer un index de partition local🎜 🎜🎜La table de base doit être une table partitionnée 🎜🎜Le nombre de partitions est le même que la table de base 🎜🎜Le nombre de sous-partitions de chaque index ; la partition est la même que la partition de la table de base correspondante ; 🎜🎜Les entrées d'index des lignes dans les sous-partitions de la table de base, sont stockées dans la sous-partition correspondante de l'index, par exemple : 🎜🎜
select count(*) from person_info where xb in (select xb_id from dic_sex); Select count(*) from n_acntbasic a where shbxdjm =:a and exists(select 1 from person_info where pid=a.pid and …); Select * from person_info where zjhm=3101….;--将会对person_info全表扫描 Select * from person_info where zjhm =‘3101…’;--才能用到索引🎜Comment créer un index global partitionné par plage🎜🎜La table de base peut être une table globale et une table partitionnée. 🎜
Select * from test where to_char(dt,’yyyymmdd’) =‘20041010’;🎜 Reconstruire l'index existant
select * from test where dt >=to_date(‘20041010’,’yyyymmdd’) and dt < to_date(‘20041010’,’yyyymmdd’) + 1🎜 Pour les partitions ; index : 🎜
Order byGroup byDistinctIn🎜Raison de la suppression de l'index🎜🎜🎜L'index n'est plus nécessaire 🎜🎜L'index ne fournit pas l'amélioration des performances attendue pour les requêtes émises par ses tables associées 🎜🎜L'application n'utilise pas l'index pour interroger ; data;🎜🎜 L'index n'est pas valide et doit être supprimé avant la reconstruction ; 🎜🎜L'index est devenu trop fragmenté et l'index doit être supprimé avant la reconstruction ; 🎜🎜Déclaration :
<br> drop index idx_name ; > drop index idx_name drop partition partition_name; <br>
🎜🎜🎜Le coût de l'indexation🎜🎜Basique table Pendant la maintenance, le système doit maintenir l'index en même temps. Des index déraisonnables affecteront sérieusement les ressources du système, principalement sur le processeur et les E/S 🎜🎜L'insertion, la mise à jour et la suppression de données génèrent une grande quantité de fichier db ; lecture séquentielle
Verrouillage en attente ; 🎜🎜Il y a des millions de données dans une table et un index est ajouté à un certain champ, mais les performances de la requête ne se sont pas améliorées. Cela peut être principalement dû à la limitation de l'index de. oracle
. 🎜🎜 L'index de oracle
a certaines restrictions d'index. Lorsque ces restrictions d'index se produisent, même si l'index a été ajouté, oracle
effectuera toujours une analyse et une requête complètes de la table. Les performances ne seront pas améliorées par rapport à l’absence d’ajout d’index. Au lieu de cela, les performances peuvent être pires en raison de la surcharge du système liée à la maintenance de l’index dans la base de données. 🎜🎜Connaissances approfondies : problèmes courants de limitation d'index🎜🎜1. Utilisez l'opérateur d'inégalité (<> ;, !=)🎜🎜Dans la situation suivante, même s'il y a un index sur la colonne dept_id
, l'instruction de requête effectue toujours une analyse complète de la table🎜rrreee🎜Mais une telle requête est effectivement nécessaire en développement, n'y a-t-il pas de solution au problème ? 🎜🎜Oui ! 🎜🎜En remplaçant le signe d'inégalité par la syntaxe ou pour l'interrogation, vous pouvez utiliser un index pour éviter une analyse complète de la table : remplacez l'instruction ci-dessus par la suivante et vous pouvez utiliser l'index. 🎜rrreee🎜2. Utiliser est nul ou n'est pas nul🎜🎜Utiliser est nul
ou est nuo nul
limitera également l'utilisation des index, car la base de données ne définit pas la valeur null
. S'il y a beaucoup de valeurs nulles dans la colonne indexée, l'index ne sera pas utilisé (sauf si l'index est un index bitmap, ce qui sera expliqué en détail dans un prochain article de blog). L'utilisation de null
dans les instructions SQL causera beaucoup de problèmes. 🎜🎜La façon de résoudre ce problème est la suivante : lors de la création de la table, définissez les colonnes qui doivent être indexées comme non nulles (not null
)🎜🎜3. Utilisez les fonctions🎜🎜Si non utilisé Pour les index basés sur des fonctions, lors de l'utilisation de fonctions dans la clause where
pour les colonnes indexées, l'optimiseur ignorera ces index. La requête suivante n'utilisera pas l'index : 🎜select * from staff where trunc(birthdate) = '01-MAY-82';
但是把函数应用在条件上,索引是可以生效的,把上面的语句改成下面的语句,就可以通过索引进行查找。
select * from staff where birthdate < (to_date('01-MAY-82') + 0.9999);
4、比较不匹配的数据类型
比较不匹配的数据类型也是难于发现的性能问题之一。下面的例子中,dept_id
是一个varchar2
型的字段,在这个字段上有索引,但是下面的语句会执行全表扫描。
select * from dept where dept_id = 900198;
这是因为oracle
会自动把where
子句转换成to_number(dept_id)=900198
,就是3所说的情况,这样就限制了索引的使用。把SQL语句改为如下形式就可以使用索引
select * from dept where dept_id = '900198';
5、使用like子句
使用like子句查询时,数据需要把所有的记录都遍历来进行判断,索引不能发挥作用,这种情况也要尽量避免。
Like
的字符串中第一个字符如果是‘%’
则用不到索引
Column1 like ‘aaa%’ 是可以的 Column1 like ‘%aaa%’用不到
6、使用IN
尽管In
写法要比exists
简单一些,exists
一般来说性能要比In要高的多
用In
还是用Exists
的时机
当in的集合比较小的时候,或者用Exists
无法用到选择性高的索引的时候,用In要好,否则就要用Exists
例:
select count(*) from person_info where xb in (select xb_id from dic_sex); Select count(*) from n_acntbasic a where shbxdjm =:a and exists(select 1 from person_info where pid=a.pid and …); Select * from person_info where zjhm=3101….;--将会对person_info全表扫描 Select * from person_info where zjhm =‘3101…’;--才能用到索引
假定TEST表的dt
字段是date
类型的并且对dt
建了索引。
如果要查‘20041010’
一天的数据.下面的方法用不到索引
Select * from test where to_char(dt,’yyyymmdd’) =‘20041010’;
而以下将会用到索引。
select * from test where dt >=to_date(‘20041010’,’yyyymmdd’) and dt < to_date(‘20041010’,’yyyymmdd’) + 1
7、如果能不用到排序,则尽量避免排序。
用到排序的情况有
集合操作。Union ,minus ,intersect
等,注:union all
是不排序的。
Order byGroup byDistinctIn
有时候也会用到排序
确实要排序的时候也尽量要排序小数据量,尽量让排序在内存中执行,有文章说,内存排序的速度是硬盘排序的1万倍。
在排序的字段上创建索引,让排序在内存中执行,加快排序速度。
8、在基于CBO的优化器(花费)下,表的统计数据过期。也可能导致不使用索引。
解决:执行表分析。获取表的最新信息。
9、获取的数据量过大,全部扫描效率更高
10、索引字段的值分散率太低,值太集中,如类型字段都是1,2, 状态类型Y-有效/N-无效。这类型的字段最好别建索引。
尽管在这些字段上建立了索引,但对全表数据区分度不大。最后还是会全表扫描。
推荐教程:《Oracle教程》
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!