当前位置: 首页 > 编程日记 > 正文

数据库索引-基本知识

为什么80%的码农都做不了架构师?>>>   hot3.png

数据库索引--基本知识

有许多因素会影响数据库性能。最明显的是数据量:您拥有的数据越多,数据库的速度就越慢。虽然有很多方法可以解决性能问题,但主要的解决方案是正确索引数据库。

为什么需要数据库索引?

要回答这个问题,我们将讲述一个故事。让我们假设我们管理一个图书馆,我们有一个数据库来存储有关我们图书的信息。对于每本书,我们存储条形码,标题,作者,流派,出版商和出版年份。我们可以将所有这些保存在一个大文件中,每行代表一本书。在这种情况下,根据记录的添加时间,书籍的顺序将按时间顺序排列。 如果我们想找一本书,我们需要扫描列表中的每一条记录。从文件的开头开始,我们将测试每条记录的搜索条件。在我们找到第一个匹配值后,搜索将被终止 - 这可能是最后一个记录!从技术上讲,这种方法有效;但随着我们的文件变大,对性能的影响将变得更加明显。在某些时候,我们的系统将变得无法使用。 此方案可以轻松应用于数据库,还有一些其他因素。例如,每个数据库记录应至少有一个唯一键。该密钥可能包含一些实际数据,但在大多数情况下,它只是一个自动分配的数值。要在我们的数据库中查找任何给定记录,我们必须使用:

  1. 主键值,如果我们知道的话。请记住,主键不是真实数据,所以我们很少有机会知道这个值。
  2. 真实的值,如书的标题或作者。

即使有了这些信息,对大量数据进行排序也很耗时。只需要查看您所在城市主图书馆中每本书的清单,即可找到一个标题!幸运的是,有一种更有效的方法可以完成任务。 为了加快速度,可以依赖于数据库索引。

什么是数据库索引?

数据库索引是一种专用数据结构,允许我们快速定位信息。它的组织方式类似于二叉树结构,左侧值较小,右侧值较大。索引可以比较树状结构中的行值,以更快地定位所需数据,而不是强制扫描整个表。

当我们在一个或多个列上创建索引时,我们将它们的值存储在新结构中,还存储指行的指针。这行为会重新组织并排序信息,但不会改变信息本身。可以将数据库索引视为书后面的索引。虽然它存储了一些实际信息,但它还包含指针,指针指向可以找到更多详细信息的位置。

按照我们的搜索条件对数据进行排序后,查找所需的记录会变得更加简单。想象一下按字母顺序排序的旧电话簿。知道某人的姓氏,名字和地址意味着您可以很快找到他们的电话号码。但是如果你只知道别人的地址和名字怎么办?没有姓氏,找到电话号码将非常困难。您可以使用反向电话簿做得更好,该目录列出了基于地址的电话号码。

在数据库中,更改搜索条件通常意味着为属性组合创建新索引。如前所述,添加这些索引需要额外的磁盘空间。添加,删除或更新值时,还会对索引进行更改。

为什么索引很重要 - 背后的数学原理

在大多数情况下,我们可以使用索引比通过数据库顺序搜索更快地找到数据。例外情况是我们的数据库中只有几条记录。如果我们在公式中表达这个,t = time,那么t<sub>using_index</sub> < t<sub>sequential search</sub>。我们可以计算这些值,计算结果是算法复杂度的公式。

算法复杂度决定了执行操作所需的时间。由于硬件配置不同,我们将使用数据集中的数据量作为参数,其中n =数据库中的记录数。所以,如果我们的图书馆有1000000本书,那么n = 1000000。

如果我们想找到哈克贝利·费恩历险记的记录,我们必须查看每个单独的书名,直到找到合适的书名。如果n = 1000000,这意味着平均会有50万本书!此顺序过程称为全表扫描,算法复杂度(n / 2)与数据集的大小直接相关。我们将使用O(n)指向它。注意:“O”用于描述算法中最重要的术语。例如,如果我们计算算法具有2n<sup>3</sup> + 4n + 21操作,则该算法的大O表示法是O(n<sup>3</sup>)。

另一方面,如果我们在title属性上使用索引,我们可以更快地找到我们的记录。如果这些书籍已按字母顺序按标题排列,我们只需查看中间的书籍(第500000条记录)。如果我们的期望值出现在此记录之前,我们将在左侧数据子集中搜索它;否则,我们会查看正确的子集。通过继续将我们的列表分成两半,我们将找到我们想要的记录。我们需要重复这个过程的最多次数是20次(2 ^ 20 = 1048576)。这种算法的复杂性表示为O(log(n))。

显然,索引方法获得了更好的结果。使用它有一个先决条件,那就是在title属性上有一个索引。这将导致更快的搜索操作,但是在添加和删除数据时,我们将丢失一些磁盘空间并且性能会降低。

示例数据库模型

Database Model

我们将使用此模型来解释本文和即将发表的文章中的索引。它旨在存储有关我们图书馆书籍的所有相关数据。

我不会进入模型细节,最重要的是要知道一些表格:

  1. 是字典,我们不期望经常改变。
  2. 包含大量数据(book,book_details,book_genre,book_author)。

如何创建索引

添加新索引需要更多磁盘空间。如果我们尝试索引每个属性和所有可能的组合,我们最终可能会遇到比我们最初的更差的性能。因此,在考虑新索引时,请记住:

  1. 仅在我们期望大量数据的表中添加索引。在我们的模型中,可能是book_details表。
  2. 只为我们希望经常搜索的属性添加索引;例如,假设人们将搜索书名是合乎逻辑的,因此book_title属性将具有索引。
  3. 如果UNIQUE无法帮助我们,请在字段中添加索引。例如,在book_details中,几本书完全有可能具有相同的名称。
  4. 如果我们为索引使用多个字段,我们必须正确地对它们进行排序。

我们可以使用以下SQL语句轻松地在book_title属性上创建索引:

CREATE INDEX book_details_idx_1 ON book_details (book_title);

以下代码,用于创建表:

-- Table: book_details
CREATE TABLE book_details (id int NOT NULL AUTO_INCREMENT,book_title varchar(255) NOT NULL,edition text NULL,publisher varchar(255) NULL,publish_year int NULL,language_id int NOT NULL,CONSTRAINT book_details_pk PRIMARY KEY (id)
)
COMMENT 'list of all book titles';
CREATE INDEX book_details_idx_1 ON book_details (book_title);
-- End of file.

使用相同的逻辑,我们将在author表上创建另外两个索引。第一个索引使用first_name列,然后使用last_name列。第二个索引反转此顺序,首先使用last_name列,然后使用first_name列。它们看起来可能相同,但索引中列的顺序至关重要;创建索引,以便索引中最左边的属性是您首先使用的属性。

为什么同一属性上有两个索引?人们可能会以几种不同的方式搜索作者。第一个索引author_idx_1允许我们仅使用first_name - last_name对或first_name属性查找记录。但它不适用于last_name-- first_name对甚至last_name属性。第二个索引author_idx_2将执行此操作。因此,无论作者的姓名如何输入搜索,都会返回有意义的结果。

我们表的CREATE TABLE语句现在如下所示:

-- tables
-- Table: author
CREATE TABLE author (id int NOT NULL AUTO_INCREMENT,first_name varchar(255) NOT NULL,last_name varchar(255) NOT NULL,birth_date date NULL COMMENT 'it is here just to distinguish authors with same first and last name (if any)',CONSTRAINT author_pk PRIMARY KEY (id)
)
COMMENT 'authors list';
CREATE INDEX author_idx_1 ON author (first_name,last_name);
CREATE INDEX author_idx_2 ON author (last_name,first_name);
-- End of file.

使用数据库索引需要注意的事情

如果一个表有一个或多个索引,它肯定会减慢INSERT操作。这是因为当记录添加到表中时,它必须在正确的位置。因此,需要调整索引,这需要时间。

如果我们期望具有索引的表发生重大更改,我们可以先删除索引,插入新记录,然后重新创建索引。根据具体情况,这可能是更快的解决方案。在我们的模型中,如果我们要添加大量新书,那么删除索引是有意义的。假设我们准备一份新书及其相关数据列表并在工作时间后运行脚本是合理的。

自动索引的一些情况

  1. 将自动为主键创建索引。在我们所有的表中,主键都被称为id。它是int类型,autoincrement设置为yes。
  2. 在MySQL InnoDB引擎中,还会自动为外键创建索引。
  3. 如果将属性定义为UNIQUE,则还会自动在其上创建索引,就像对主键一样。

在以上情况下,都会在键值上创建索引,从而加快搜索操作(当使用id作为搜索参数时)。这有助于我们知道id并且我们想要检索,更新或删除该记录的值。 索引非常强大。它们允许我们更快地执行搜索和排序操作。但是这个速度需要付出代价:创建索引需要磁盘空间并且可能会降低其他操作的速度。

原谅链接:https://www.vertabelo.com/blog/technical-articles/all-about-indexes-the-very-basics

转载于:https://my.oschina.net/zho/blog/3016252

相关文章:

Microsoft Enterprise Library 5.0 系列(八) Unity Dependency Injection and Interception

依赖注入容器Unity: Unity的构造类似于Castle中的IOC&#xff08;控制反转 或者叫依赖注入&#xff09;容器,我们使用抽象接口来隔离使用者和具体实现之间的依赖关系&#xff0c;但是不管再怎么抽象&#xff0c;最终还是要创建具体实现类的实例&#xff0c;这种创建具体实现类的…

pycharm 使用小结

1.pycharm 自动换行,显示行号,缩进向导 在代码右侧右键 2.自动注释/取消注释 ctrl /转载于:https://www.cnblogs.com/xuesu/p/4755086.html

golang socket读写同时_epoll在Golang的应用

使用Golang可以轻松地为每一个TCP连接创建一个协程去服务而不用担心性能问题&#xff0c;这是因为Go内部使用goroutine结合IO多路复用实现了一个“异步”的IO模型&#xff0c;这使得开发者不用过多的关注底层&#xff0c;而只需要按照需求编写上层业务逻辑。这种异步的IO是如何…

HTTP 2.0与OkHttp

HTTP 2.0是对1.x的扩展而非替代&#xff0c;之所以是“2.0”&#xff0c;是因为它改变了客户端与服务器之间交换数据的方式。HTTP 2.0增加了新的二进制分帧数据层&#xff0c;而这一层并不兼容之前的HTTP 1.x服务器及客户端——是谓2.0。  在正式介绍HTTP 2.0之前&#xff0c;…

根据“坐标”生成趋势图

数据库环境&#xff1a;SQL SERVER 2008R2 有一“坐标”表t&#xff0c;表结构如下&#xff1a; id int&#xff0c; num int 字段id是序号&#xff0c;递增且连续&#xff0c;字段num是数值类型。id可以看成是坐标轴的横轴&#xff0c;num则跟纵轴有关系&…

Winform程序怎么降低占用的内存?

1 Winform程序怎么降低占用的内存&#xff1f;winform程序占用的内存数一直居高不下&#xff0c;提供给用户的手册中说明内存不能大于50MB,但是每次运行的时候&#xff0c;内存都会飙高到100多MB. 2 3 后来终于发现了一个方法&#xff0c;可以解决这个问题&#xff1a; …

mysql关系表控制_mysql表关系

一、表的详细操作1.修改表名alter table 旧表名 rename 新表名;​2.修改表的引擎与字符编码alter table 表名 engine"引擎名" charset"编码名";​3.复制表 *#结构create table 新表名 like 旧表名;eg:1create table nt like tt;#将tt的表结构复制到新表nt中…

【Python3爬虫】常见反爬虫措施及解决办法(二)...

【Python3爬虫】常见反爬虫措施及解决办法&#xff08;二&#xff09; 这一篇博客&#xff0c;还是接着说那些常见的反爬虫措施以及我们的解决办法。同样的&#xff0c;如果对你有帮助的话&#xff0c;麻烦点一下推荐啦。 一、防盗链 这次我遇到的防盗链&#xff0c;除了前面说…

【原创】ListView快速滚动至新添加一行(自动滚动)

在C#开发中我们经常要开发一些日志系统&#xff0c;尤其是基于ListView的日志显示系统。但是当日志增多是你是否有一些困扰&#xff0c;就是它为什么不会自动滚动至最后一行。以下是一小段代码&#xff0c;希望可以帮助你. public void addLog(string logString) { lock (_lock…

MFC调用CFileDialog之后目录居然会改变,调试了好久终于发现是这个问题

MFC调用CFileDialog之后目录居然会改变&#xff0c;调试了好久终于发现是这个问题&#xff0c;上网搜了下&#xff0c;发现也有人和我出现相同的问题。他的博客如下&#xff1a; http://www.programlife.net/current-directory-changed-after-using-cfiledialog.html MFC调用C…

mysqlls_mysql基本命令

1、Mysql启动命令&#xff1a;命令行内容为&#xff1a;\>net start mysql运行情况如图1所示&#xff1a;图1(Mysql启动命令)2、连接Mysql服务器&#xff1a;命令行内容为&#xff1a;\>mysql -u root -h hostaddress -p password其中&#xff0c;root为Mysql的用户名&a…

2019年3月

分包加载 使用公众号登录微信提示  "公众号暂不支持此种登录方式" 使用已经注册过的手机号注册新的微信账号提示  "你申请注册的手机号已被其他微信号绑定,暂时不能使用该手机号注册" https://github.com/witcat/LayaWxCacheFromZip /******/ (functio…

8天学通MongoDB——第三天 细说高级操作

原文地址:http://www.cnblogs.com/huangxincheng/archive/2012/02/21/2361205.html 今天跟大家分享一下mongodb中比较好玩的知识&#xff0c;主要包括&#xff1a;聚合&#xff0c;游标。 一&#xff1a; 聚合 常见的聚合操作跟sql server一样&#xff0c;有&#xff1a;count&…

UVA 10954 Add All

UVA_10954 看了别人解题报告之后发现累加的过程可以这样操作&#xff0c;每次取最小的两个元素加和&#xff0c;然后把和当作一个新元素放进集合&#xff0c;直到剩下一个元素&#xff0c;然后把中间结果加起来就是要求的结果。实际上这个题目就是哈弗曼编码&#xff0c;在LRJ树…

Java将mysql输出csv,如何从Java中的Access数据库导出表并将其保存到.csv

I am trying to export a lot of large tables from a MS Access db with java using the jdbc:odbc bridge. I wanted to save these tables to a CSV file first was wondering what would the best way to do this would be? any help would be appreciated.解决方案Fetch …

windows下nodejs express安装及入门网站,视频资料,开源项目介绍

windows下nodejs express安装及入门网站,视频资料&#xff0c;开源项目介绍&#xff0c;pm2,supervisor,npm,Pomelo,Grunt安装使用注意事项等总结 第一步&#xff1a;下载安装文件下载地址&#xff1a;官网http://www.nodejs.org/download/ 第二步&#xff1a;安装nodejs下载完…

python 之 pip、pypdf2 安装与卸载

pip是个啥&#xff1f; pip 是一个现代的&#xff0c;通用的 Python 包管理工具。提供了对 Python 包的查找、下载、安装、卸载的功能。 第一步&#xff1a;pip 下载&#xff1a;https://pypi.org/project/pip/#files 第二步&#xff1a;解压&#xff0c;进入目录python pip\pi…

eclipse 3.55安装j2ee开发工具

选择help--->install new software -->work width --选择下拉框选择要安装插件转载于:https://www.cnblogs.com/yjhrem/articles/2309602.html

mysql中没有内置函数_[mysql]MySQL中的内置函数

用在select 语句&#xff0c;以及子句where order by hacing 中 update delete函数中可以将字段名作为字段来用&#xff0c;变量的值就是这个列对应的每一行记录。一、字符串函数php中用到的函数&#xff0c;mysql中大部分也提供了1、CONCAT(”字符串”,字段&…

tiny210V2 Uboot kernel filesystem 烧写和启动

1.sd启动 将u-boot镜像写入SD卡 将SD卡通过读卡器接上电脑&#xff08;或直接插入笔记本卡槽&#xff09;&#xff0c;通过"cat /proc/partitions"找出SD卡对应的设备&#xff0c;我的设备节点是/dev/sdb.执行下面的命令$sudo dd iflagdsync oflagdsync iftiny210-ub…

Linux下Shell日期的格式

2019独角兽企业重金招聘Python工程师标准>>> 不管是哪种语言&#xff0c;日期/时间都是一个非常重要的值。比如我们保存日志的时候&#xff0c;往往是某个前缀再加上当前时间&#xff0c;这样日志文件名称就可以做到唯一。在Shell环境里&#xff0c;我们获取时间的命…

usaco 6.1

6.1.2 rectbarn 首先要注意空间的消耗,3000*3000 大概10m的样子(最多16m),只够开个char,本想套用big barn的dp方法,定义struct [i,j]{int l;int h}来表示以(i,j)为右上顶点的矩形,貌似这样会爆,只好考虑其它解法(参考wc2003王知昆的论文). 大概思路: 定义h[i,j],l[i,j],r[i,j]分…

docker mysql详解_Docker轻松入门(详解)

一 Docker简介Docker 是一个开源的应用容器引擎&#xff0c;基于 Go 语言 并遵从Apache2.0协议开源。Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中&#xff0c;然后发布到任何流行的 Linux 机器上&#xff0c;也可以实现虚拟化。容器是完全使用沙…

[恢]hdu 2014

2011-12-12 05:46:08 地址&#xff1a;http://acm.hdu.edu.cn/showproblem.php?pid2014 题意&#xff1a;中文题。 mark&#xff1a;wa了3次&#xff01;&#xff01;&#xff01;因为敲错变量&#xff01;&#xff01;&#xff01;min敲成了num&#xff0c;各种二。可能是困了…

java在继承中父类的成员变量是否会被子类所覆盖

假如 父类 int num 7&#xff1b;子类 int num 9&#xff1b;父类是否会被子类所覆盖? 给你看两个例子&#xff1a; 第一个例子&#xff1a; 第二个例子&#xff1a; 这两个例子的区别只有一句话 由此证明了子类从父类继承的时候 如果有同名的成员变量 默认情况下 父类的成…

长连接及在Node中的应用——HTTP/1.1 keep-alive

HTTP请求都要经过TCP三次握手建立连接&#xff0c;四次分手断开连&#xff0c;如果每个HTTP请求都要建立TCP连接的话是极其费时的&#xff0c;因此HTTP/1.1中浏览器默认开启了Connection: keep-alive。 请求头中的这个属性的作用可以在请求完成后&#xff0c;保持TCP连接一段时…

python 桑基图 地理坐标_【转载】Python数据可视化-实现Sankey桑基图

根据不完整统计&#xff0c;90%想用sankey图的朋友都是因为被它炫酷的外表所吸引&#xff0c;举个例子&#xff1a;在这里插入图片描述关于sankey图的定义是这样描述的&#xff1a;即桑基能量分流图&#xff0c;也叫桑基能量平衡图。它是一种特定类型的流程图&#xff0c;图中延…

[恢]hdu 2015

2011-12-14 05:49:09 地址&#xff1a;http://acm.hdu.edu.cn/showproblem.php?pid2015 题意&#xff1a;中文&#xff0c;忒麻烦了。 代码&#xff1a; # include <stdio.h>int main (){int n, m, flag ;int i, sum, cnt ;while (~scanf ("%d%d", &n, &a…

http://www.shanghaihaocong.com-WORDPRESS开发的企业主题站

wordpress是世界上使用最多的php开源博客系统&#xff0c;功能强大&#xff0c;而且拥有众多的插件&#xff0c;可扩展性强。 最近&#xff0c;我也用它做了一个企业网站&#xff0c;欢迎浏览&#xff1a;http://www.shanghaihaocong.com&#xff0c;上海灏璁实业有限公司转载于…

蓝桥杯 扑克序列(全排列)

扑克序列 A A 2 2 3 3 4 4&#xff0c; 一共4对扑克牌。请你把它们排成一行。要求&#xff1a;两个A中间有1张牌&#xff0c;两个2之间有2张牌&#xff0c;两个3之间有3张牌&#xff0c;两个4之间有4张牌。 请填写出所有符合要求的排列中&#xff0c;字典序最小的那个。 例如&a…