iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >什么是建立索引
  • 1069
分享到

什么是建立索引

2024-04-02 19:04:59 1069人浏览 安东尼
摘要

这篇文章主要讲解了“什么是数据库建立索引”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“什么是数据库建立索引”吧! 这里想把之前

这篇文章主要讲解了“什么是数据库建立索引”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“什么是数据库建立索引”吧!

这里想把之前的索引学习笔记总结一下:

    首先明白为什么索引会增加速度,DB在执行一条sql语句的时候,默认的方式是根据搜索条件进行全表扫描,遇到匹配条件的就加入搜索结果集合。如果我们对某一字段增加索引,查询时就会先去索引列表中一次定位到特定值的行数,大大减少遍历匹配的行数,所以能明显增加查询的速度。那么在任何时候都应该加索引么?这里有几个反例:1、如果每次都需要取到所有表记录,无论如何都必须进行全表扫描了,那么是否加索引也没有意义了。2、对非唯一的字段,例如“性别”这种大量重复值的字段,增加索引也没有什么意义。3、对于记录比较少的表,增加索引不会带来速度的优化反而浪费了存储空间,因为索引是需要存储空间的,而且有个致命缺点是对于update/insert/delete的每次执行,字段的索引都必须重新计算更新。

    那么在什么时候适合加上索引呢?我们看一个Mysql手册中举的例子,这里有一条sql语句:

    SELECT c.companyID, c.companyName FROM Companies c, User u WHERE c.companyID = u.fk_companyID AND c.numEmployees >= 0 AND c.companyName LIKE '%i%' AND u.groupID IN (SELECT g.groupID FROM Groups g WHERE g.groupLabel = 'Executive')

    这条语句涉及3个表的联接,并且包括了许多搜索条件比如大小比较,Like匹配等。在没有索引的情况下mysql需要执行的扫描行数是 77721876行。而我们通过在companyID和groupLabel两个字段上加上索引之后,扫描的行数只需要134行。在Mysql中可以通过 Explain Select来查看扫描次数。可以看出来在这种联表和复杂搜索条件的情况下,索引带来的性能提升远比它所占据的磁盘空间要重要得多。

    那么索引是如何实现的呢?大多数DB厂商实现索引都是基于一种数据结构——B树。因为B树的特点就是适合在磁盘等直接存储设备上组织动态查找表。B树的定义是这样的:一棵m(m>=3)阶的B树是满足下列条件的m叉树:

    1、每个结点包括如下作用域(j, p0, k1, p1, k2, p2, ... ki, pi) 其中j是关键字个数,p是孩子指针

    2、所有叶子结点在同一层上,层数等于树高h

    3、每个非根结点包含的关键字个数满足[m/2-1]<=j<=m-1

    4、若树非空,则根至少有1个关键字,若根非叶子,则至少有2棵子树,至多有m棵子树

    看一个B树的例子,针对26个英文字母的B树可以这样构造:

什么是建立索引

    可以看到在这棵B树搜索英文字母复杂度只为o(m),在数据量比较大的情况下,这样的结构可以大大增加查询速度。然而有另外一种数据结构查询的虚度比B树更快——散列表。Hash表的定义是这样的:设所有可能出现的关键字集合为u,实际发生存储的关键字记为k,而|k|比|u|小很多。散列方法是通过散列函数h将u映射到表T[0,m-1]的下标上,这样u中的关键字为变量,以h为函数运算结果即为相应结点的存储地址。从而达到可以在o(1)的时间内完成查找。
    然而散列表有一个缺陷,那就是散列冲突,即两个关键字通过散列函数计算出了相同的结果。设m和n分别表示散列表的长度和填满的结点数,n/m为散列表的填装因子,因子越大,表示散列冲突的机会越大。
    因为有这样的缺陷,所以数据库不会使用散列表来做为索引的默认实现,Mysql宣称会根据执行查询格式尝试将基于磁盘的B树索引转变为和合适的散列索引以追求进一步提高搜索速度。我想其它数据库厂商也会有类似的策略,毕竟在数据库战场上,搜索速度和管理安全一样是非常重要的竞争点。

基本概念介绍:

索引

使用索引可快速访问数据库表中的特定信息。索引是对数据库表中一列或多列的值进行排序的一种结构,例如 employee 表的姓(lname)列。如果要按姓查找特定职员,与必须搜索表中的所有行相比,索引会帮助您更快地获得该信息。

索引提供指向存储在表的指定列中的数据值的指针,然后根据您指定的排序顺序对这些指针排序。数据库使用索引的方式与您使用书籍中的索引的方式很相似:它搜索索引以找到特定值,然后顺指针找到包含该值的行。

在数据库关系图中,您可以在选定表的“索引/键”属性页中创建、编辑或删除每个索引类型。当保存索引所附加到的表,或保存该表所在的关系图时,索引将保存在数据库中。有关详细信息,请参见创建索引。

注意;并非所有的数据库都以相同的方式使用索引。有关更多信息,请参见数据库服务器注意事项,或者查阅数据库文档。

作为通用规则,只有当经常查询索引列中的数据时,才需要在表上创建索引。索引占用磁盘空间,并且降低添加、删除和更新行的速度。在多数情况下,索引用于数据检索的速度优势大大超过它的。

索引列

可以基于数据库表中的单列或多列创建索引。多列索引使您可以区分其中一列可能有相同值的行。

如果经常同时搜索两列或多列或按两列或多列排序时,索引也很有帮助。例如,如果经常在同一查询中为姓和名两列设置判据,那么在这两列上创建多列索引将很有意义。

确定索引的有效性:

  • 检查查询的 WHERE 和 JOIN 子句。在任一子句中包括的每一列都是索引可以选择的对象。

  • 对新索引进行试验以检查它对运行查询性能的影响。

  • 考虑已在表上创建的索引数量。最好避免在单个表上有很多索引。

  • 检查已在表上创建的索引的定义。最好避免包含共享列的重叠索引。

  • 检查某列中唯一数据值的数量,并将该数量与表中的行数进行比较。比较的结果就是该列的可选择性,这有助于确定该列是否适合建立索引,如果适合,确定索引的类型。

索引类型

根据数据库的功能,可以在数据库设计器中创建三种索引:唯一索引、主键索引和聚集索引。有关数据库所支持的索引功能的详细信息,请参见数据库文档。

提示:尽管唯一索引有助于定位信息,但为获得最佳性能结果,建议改用主键或唯一约束。

唯一索引

唯一索引是不允许其中任何两行具有相同索引值的索引。

当现有数据中存在重复的键值时,大多数数据库不允许将新创建的唯一索引与表一起保存。数据库还可能防止添加将在表中创建重复键值的新数据。例如,如果在 employee 表中职员的姓 (lname) 上创建了唯一索引,则任何两个员工都不能同姓。

主键索引

数据库表经常有一列或列组合,其值唯一标识表中的每一行。该列称为表的主键。

在数据库关系图中为表定义主键将自动创建主键索引,主键索引是唯一索引的特定类型。该索引要求主键中的每个值都唯一。当在查询中使用主键索引时,它还允许对数据的快速访问。

聚集索引

在聚集索引中,表中行的物理顺序与键值的逻辑(索引)顺序相同。一个表只能包含一个聚集索引。

如果某索引不是聚集索引,则表中行的物理顺序与键值的逻辑顺序不匹配。与非聚集索引相比,聚集索引通常提供更快的数据访问速度。

建立方式和注意事项

最普通的情况,是为出现在where子句的字段建一个索引。为方便讲述,我们先建立一个如下的表。

CREATE TABLE mytable (

 id serial primary key,

 cateGory_id int not null default 0,

 user_id int not null default 0,

 aDDDate int not null default 0

);

如果你在查询时常用类似以下的语句:

 SELECT * FROM mytable WHERE category_id=1;

最直接的应对之道,是为category_id建立一个简单的索引:

 CREATE INDEX mytable_categoryid

 ON mytable (category_id);

OK.如果你有不止一个选择条件呢?例如:

 SELECT * FROM mytable WHERE category_id=1 AND user_id=2;

你的第一反应可能是,再给user_id建立一个索引。不好,这不是一个最佳的方法。你可以建立多重的索引。

CREATE INDEX mytable_categoryid_userid ON mytable (category_id,user_id);

注意到我在命名时的习惯了吗?我使用"表名_字段1名_字段2名"的方式。你很快就会知道我为什么这样做了。

现在你已经为适当的字段建立了索引,不过,还是有点不放心吧,你可能会问,数据库会真正用到这些索引吗?测试一下就OK,对于大多数的数据库来说,这是很容易的,只要使用EXPLAIN命令:

EXPLAIN

 SELECT * FROM mytable

WHERE category_id=1 AND user_id=2;

 This is what Postgres 7.1 returns (exactly as I expected)

 NOTICE: QUERY PLAN:

 Index Scan using mytable_categoryid_userid on

 mytable (cost=0.00..2.02 rows=1 width=16)

EXPLAIN

以上是postgres的数据,可以看到该数据库在查询的时候使用了一个索引(一个好开始),而且它使用的是我创建的第二个索引。看到我上面命名的好处了吧,你马上知道它使用适当的索引了。

接着,来个稍微复杂一点的,如果有个ORDER BY字句呢?不管你信不信,大多数的数据库在使用order by的时候,都将会从索引中受益。

 SELECT * FROM mytable

WHERE category_id=1 AND user_id=2

 ORDER BY adddate DESC;

很简单,就象为where字句中的字段建立一个索引一样,也为ORDER BY的字句中的字段建立一个索引:

 CREATE INDEX mytable_categoryid_userid_adddate

 ON mytable (category_id,user_id,adddate);

 注意: "mytable_categoryid_userid_adddate" 将会被截短为

"mytable_categoryid_userid_addda"

 CREATE

 EXPLAIN SELECT * FROM mytable

WHERE category_id=1 AND user_id=2

 ORDER BY adddate DESC;

 NOTICE: QUERY PLAN:

 Sort (cost=2.03..2.03 rows=1 width=16)

-> Index Scan using mytable_categoryid_userid_addda

 on mytable (cost=0.00..2.02 rows=1 width=16)

 EXPLAIN

看看EXPLAIN的输出,数据库多做了一个我们没有要求的排序,这下知道性能如何受损了吧,看来我们对于数据库的自身运作是有点过于乐观了,那么,给数据库多一点提示吧。

为了跳过排序这一步,我们并不需要其它另外的索引,只要将查询语句稍微改一下。这里用的是postgres,我们将给该数据库一个额外的提示--在 ORDER BY语句中,加入where语句中的字段。这只是一个技术上的处理,并不是必须的,因为实际上在另外两个字段上,并不会有任何的排序操作,不过如果加入,postgres将会知道哪些是它应该做的。

 EXPLAIN SELECT * FROM mytable

WHERE category_id=1 AND user_id=2

 ORDER BY category_id DESC,user_id DESC,adddate DESC;

 NOTICE: QUERY PLAN:

 Index Scan Backward using

mytable_categoryid_userid_addda on mytable

 (cost=0.00..2.02 rows=1 width=16)

 EXPLAIN

现在使用我们料想的索引了,而且它还挺聪明,知道可以从索引后面开始读,从而避免了任何的排序。

以上说得细了一点,不过如果你的数据库非常巨大,并且每日的页面请求达上百万算,我想你会获益良多的。不过,如果你要做更为复杂的查询呢,例如将多张表结合起来查询,特别是where限制字句中的字段是来自不止一个表格时,应该怎样处理呢?我通常都尽量避免这种做法,因为这样数据库要将各个表中的东西都结合起来,然后再排除那些不合适的行,搞不好开销会很大。

如果不能避免,你应该查看每张要结合起来的表,并且使用以上的策略来建立索引,然后再用EXPLAIN命令验证一下是否使用了你料想中的索引。如果是的话,就OK。不是的话,你可能要建立临时的表来将他们结合在一起,并且使用适当的索引。

要注意的是,建立太多的索引将会影响更新和插入的速度,因为它需要同样更新每个索引文件。对于一个经常需要更新和插入的表格,就没有必要为一个很少使用的where字句单独建立索引了,对于比较小的表,排序的开销不会很大,也没有必要建立另外的索引。

以上介绍的只是一些十分基本的东西,其实里面的学问也不少,单凭EXPLAIN我们是不能判定该方法是否就是最优化的,每个数据库都有自己的一些优化器,虽然可能还不太完善,但是它们都会在查询时对比过哪种方式较快,在某些情况下,建立索引的话也未必会快,例如索引放在一个不连续的存储空间时,这会增加读磁盘的负担,因此,哪个是最优,应该通过实际的使用环境来检验。

在刚开始的时候,如果表不大,没有必要作索引,我的意见是在需要的时候才作索引,也可用一些命令来优化表,例如MySQL可用"OPTIMIZE TABLE"。

感谢各位的阅读,以上就是“什么是数据库建立索引”的内容了,经过本文的学习后,相信大家对什么是数据库建立索引这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

您可能感兴趣的文档:

--结束END--

本文标题: 什么是建立索引

本文链接: https://www.lsjlt.com/news/61151.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 什么是建立索引
    这篇文章主要讲解了“什么是数据库建立索引”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“什么是数据库建立索引”吧! 这里想把之前...
    99+
    2024-04-02
  • mysql建立索引的规则是什么
    建立索引的规则如下: 唯一性:索引列的值应该是唯一的,这样可以通过索引来确保数据的唯一性。 选择性:索引列的值应该具有高选择...
    99+
    2024-04-09
    mysql
  • mysql建立索引的方法是什么
    这篇文章主要介绍了mysql建立索引的方法是什么,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。1、最左前缀匹配原则,非常重要的原则,mysql会一直向右匹配直到遇到范围查询(...
    99+
    2023-06-15
  • mysql索引建立的原则是什么
    小编给大家分享一下mysql索引建立的原则是什么,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!尽量选择区分度高的列来建立索引。频繁查询列适合建立索引。遇到联合索引时,想想最左边的匹配原则。like模糊查询时,%在前面时才会...
    99+
    2023-06-25
  • MySQL索引建立的基本原则是什么
    MySQL索引建立的基本原则有以下几点: 索引应该建立在经常用于检索数据的列上,比如在WHERE子句、JOIN子句或OR...
    99+
    2024-03-13
    MySQL
  • navicat索引怎么建立
    navicat 中建立索引可显著提高数据库查询性能。通过右键单击表并选择 "编辑表",在 "索引" 选项卡中选择 "添加索引",可配置索引名称、列、索引类型和唯一性。navicat 支持...
    99+
    2024-04-24
    navicat
  • mysql为什么建立索引比较快
    这期内容当中小编将会给大家带来有关mysql为什么建立索引比较快,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。mysql为什么建立索引比较快索引可以快速检索,减少I/O次...
    99+
    2024-04-02
  • 怎么用SQL建立索引
    这篇文章主要讲解了“怎么用SQL建立索引”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么用SQL建立索引”吧!用SQL建立索引为了给一个表建立索引,启动任...
    99+
    2024-04-02
  • mongodb怎么建立hash索引
    在MongoDB中,可以通过使用`createIndex()`方法来建立一个哈希索引。首先,连接到MongoDB数据库。然后,选择要...
    99+
    2023-09-06
    mongodb
  • MySQL为数据表建立索引的原则是什么
    这篇文章给大家分享的是有关MySQL为数据表建立索引的原则是什么的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。面试题:索引是什么?索引的优点?索引的缺点?在建立索引的时候都有哪些需要考虑的因素呢为数据表建立索引的...
    99+
    2023-06-29
  • mysql如何建立索引
    小编给大家分享一下mysql如何建立索引,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!mysql索引怎么建立1.添加PRIMAR...
    99+
    2024-04-02
  • mongodb怎么建立唯一索引
    在MongoDB中,可以使用`createIndex()`方法来建立唯一索引。以下是建立唯一索引的步骤:1. 连接到MongoDB数...
    99+
    2023-08-23
    mongodb
  • SQL之SQL索引怎么建立
    SQL索引是用于提高查询效率的一种数据结构。通过建立索引,可以让数据库快速定位到存储在表中的数据。下面是建立SQL索引的一些常见方法...
    99+
    2023-09-14
    SQL
  • navicat建立索引的方法
    小编给大家分享一下navicat建立索引的方法,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!打开Navicat。打开数据表所在的...
    99+
    2024-04-02
  • 什么是索引,在Oracle中如何创建索引
    索引是一种数据结构,它可以提高数据库检索数据的性能。索引是一个指向表中数据位置的指针,可以帮助数据库引擎更快地定位和检索数据。 在O...
    99+
    2024-04-09
    Oracle
  • word中如何建立索引
    在Word中可以通过以下步骤建立索引:1. 首先,在文档中选择要建立索引的文本或词汇。2. 在菜单栏中选择“引用”选项卡。3. 在“...
    99+
    2023-09-15
    Word
  • sql索引怎么建立与使用
    SQL索引可以通过CREATE INDEX语句来建立,语法如下:```CREATE INDEX index_nameON table...
    99+
    2023-08-18
    sql
  • 怎么为CSS文件建立索引
    本篇内容介绍了“怎么为CSS文件建立索引”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、CSS 样式文件分解对于小项目,在写代码之前,按页...
    99+
    2023-06-27
  • MySQL 中主键是否自动建立索引?
    是的,主键在 MySQL 中会自动索引,因为主键、索引等都存储在 B 树中。所有引擎包括InnoDB和MyISAM都自动支持主键索引。 主键在 InnoDB、MyISAM 和其他引擎中隐式索引。 让我们创建一个带有主键的表 - mysql...
    99+
    2023-10-22
  • sqlserver索引怎么建立与使用
    在SQL Server中,索引可以帮助加快查询的速度,提高数据库的性能。以下是如何建立和使用索引的一般步骤: 创建索引: 可以通过...
    99+
    2024-04-09
    sqlserver
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作