在执行SQL选择期间,数据库总是会引用表的元数据,而不管对SELECT a,b,c来说是否为SELECT *。为什么?因为那是有关系统表的结构和布局的信息所在的位置。
它必须阅读此信息有两个原因。一,简单地编译语句。它需要确保至少指定一个现有表。此外,自上次执行语句以来,数据库结构可能已更改。
现在,很明显,数据库元数据已缓存在系统中,但仍需要处理。
接下来,使用元数据生成查询计划。每次编译语句时也会发生这种情况。同样,这是针对缓存的元数据运行的,但始终可以完成。
唯一不执行此处理的时间是在DB使用预编译查询或已缓存先前查询时。这是使用绑定参数而不是文字SQL的参数。“ SELECT * FROM TABLE WHERE键= 1”与“ SELECT * FROM TABLE WHERE键=?”不同。并且呼叫上绑定了“ 1”。
数据库在很大程度上依赖页面缓存。许多现代数据库的大小足以完全容纳在内存中(或者,也许我应该说,现代内存足以容纳许多数据库)。然后,后端的主要I / O成本是日志记录和页面刷新。
但是,如果您仍在为数据库打磁盘,则许多系统所做的主要优化是依靠索引中的数据,而不是表本身。
如果你有:
CREATE TABLE customer (
id INTEGER NOT NULL PRIMARY KEY,
name VARCHAR(150) NOT NULL,
city VARCHAR(30),
state VARCHAR(30),
zip VARCHAR(10));
CREATE INDEX k1_customer ON customer(id, name);
然后,如果执行“ SELECT ID,从FROM客户WHERE ID = 1命名”,则DB很可能会从索引而不是从表中提取此数据。
为什么?无论如何,它都可能会使用索引来满足查询(相对于表扫描),即使在where子句中未使用“名称”,该索引仍将是查询的最佳选择。
现在,数据库具有满足查询所需的所有数据,因此没有理由直接访问表页面。使用索引可以减少磁盘流量,因为索引中的行密度通常比表中的行高。
这是一些数据库使用的特定优化技术的波浪形解释。许多人有几种优化和调整技术。
最后,SELECT *对于必须手动键入的动态查询很有用,我永远不会将其用于“真实代码”。识别各个列为DB提供了更多信息,可用于优化查询,并为代码提供了更好的控制,以防止架构更改等。
SELECT
查询执行/处理是从数据库到数据库中的不同。