查找在数据库中如何工作?

时间:2018-10-04 07:06:37

标签: java database

我试图了解查询在数据库中的工作方式。在数据库中,所有内容都在文件系统的磁盘上。

所以可以说,如果我使用某个filter子句查询具有数百万条记录的表中的数据,那么所有记录将首先加载到内存中,然后 它查找特定数据还是发生其他事情?是吗?

我的理解是,无论我们运行什么查询,所有数据库表的数据都会加载到内存中,然后执行操作。正确吗?

第二,如果我在表中有8gb的数据,而在4gb的ram中有数据,那将可以从数据库中获取数据?通常它可以工作,但是可以在磁盘上搜索吗?真的吗

请分享您的观点。

谢谢

2 个答案:

答案 0 :(得分:1)

如果您正在谈论使用SQL的关系数据库,那么您的假设是错误的。

数据库不会一次将所有行加载到内存中以仅找到其中的一行。如果where子句中的列上有索引,则该索引将用于查找所需的行。

如果没有索引,则数据库可能会从表中的另一行开始读取,检查值并从WHERE中丢弃不符合过滤条件的值条款。因此,在任何给定时间,只有一小部分行保留在内存中(多少取决于数据库的实现,所选择的配置和执行计划)。

如果行不适合内存,数据库可能会在磁盘上执行操作。例如。如果需要某种行,那么如果没有足够的内存将所有行保留在内存中,则可以在磁盘上完成此操作。

返回结果时,它也不保存在内存中。具体的实现方式取决于特定的DBMS产品。

答案 1 :(得分:1)

这里是简化的概述。

严重的关系数据库引擎(例如Postgres或MS SQL Server或Oracle)经过高度优化,可在对副本进行高速缓存的同时管理对写入持久性存储的数据的有效访问。

数据库>内存

数据库就像任何应用程序一样,将数据从存储设备加载到内存中以进行处理,读取和写入。当内存已满时,将清除当前不需要的数据,然后可以将其他数据从存储器加载到内存中。修改后的行首先在内存中更改,然后写入存储。

这意味着存储的数据库可能比可用内存大得多。例如,您可能在具有8 GB内存的计算机上存储一个TB(1,000 gigs)大小的数据库。为了获得最佳性能,您希望数据库可以访问所需数量的内存,以容纳最近使用的所有数据。更多线程更多的用户执行更多的查询/插入/更新意味着您将受益于更多的内存。只有最近访问的表中最近使用的行才需要在内存中。数据库的主要工作是根据需要将部分所需的数据块从存储区加载到内存中。因此,整个数据库不必完全加载到内存中。

默认情况下,对表的查询会导致将每一行加载到内存中。

行的副本可以作为高速缓存保存在内存中。每个数据库引擎实现都有自己的规则,用于确定哪些行应保留在缓存中以及保留多长时间。用作高速缓存的内存量可以由数据库管理员(DBA)配置。

diagram of database in storage with some rows copied into cache in memory

下次查询表并将要从存储中加载表的行时,将首先检查内存中的缓存,以查看是否存在足够的行副本。如果是这样,则无需从存储中加载。在内存中使用缓存的副本极大地提高了性能。

通过检查每一行来执行查询被称为顺序扫描或类似术语。

如果您知道特定列的数据将成为频繁查询的目标,则应通知DBA,以便她可以告诉数据库在该列上建立和维护索引。索引就像图书馆中的老式卡片目录一样,在其中按照自己的排序结构复制和组织书籍的某些部分(例如书名或作者)。在卡片目录的小抽屉中查找条目比在图书馆大楼的所有书架上漫步来查找书籍要容易得多。

索引中复制和排序的数据将保存在存储器中。像行一样,索引的一部分可以保留在高速缓存中,以便更快地进行搜索。

如果存在索引,则查询引擎将对其进行查询,而不是在可行且高效的情况下查询存储的行。通过遍历索引而不是行来执行查询被称为索引扫描或类似术语。

索引具有成本。它们需要数据库的工作,并且需要一些存储空间。当通过更改索引列中的数据来修改行时,数据库必须更新索引以及行。数据库必须在处理并发冲突时以线程安全,高效,事务的方式进行操作。

复杂的查询通常包含索引扫描和顺序扫描的组合。