如果我只需要2/3列,而是查询SELECT *而不是在select查询中提供这些列,那么关于更多/更少I / O或内存的性能是否会有所下降?
SELECT *
如果我确实选择了*,则可能会出现网络开销。
但是在选择操作中,数据库引擎是否总是从磁盘中提取原子元组,还是仅提取在选择操作中请求的那些列?
如果它总是拉一个元组,则I / O开销是相同的。
同时,如果它拉出一个元组,从元组中剥离请求的列可能会占用内存。
因此,在这种情况下,select someColumn将比select *具有更多的内存开销。
它总是拉一个元组(表被垂直分割的情况除外- 分成几列),因此,要回答您提出的问题,从性能的角度来看并不重要。但是,由于许多其他原因,(在下面)您应该始终按名称专门选择想要的那些列。
它总是拉出一个元组,因为(在我熟悉的每个供应商RDBMS中),所有内容(包括表数据)的底层磁盘存储结构都基于已定义的 I / O页 (在SQL Server中,例如,每个Page 8 KB)。每个I / O的读取或写入都是按Page ..即,每个写入或读取都是一个完整的数据页面。
由于这种潜在的结构约束,结果是数据库中的每一行数据必须始终位于一页上。它不能跨越多个数据页(除了blob之类的特殊事物外,其中实际的blob数据存储在单独的分页块中,而实际的表行列则仅获得一个指针…)。但是这些例外只是例外,通常不适用,除非在特殊情况下(对于特殊类型的数据,或针对特殊情况的某些优化), 即使在这些特殊情况下,通常,数据本身的实际表行(包含指向Blob或其他任何内容的实际数据的指针),它必须存储在单个IO页上…
例外。唯一可以确定的位置Select *是在子查询中,位于preExists或Not Existspredicate子句之后,例如:
Select *
Exists
Not Exists
Select colA, colB From table1 t1 Where Exists (Select * From Table2 Where column = t1.colA)
编辑:要解决@MikeSherer的评论,是的,从技术上讲,这是对的,对您的特殊情况和美学都有一点定义。首先,即使请求的列集是存储在某个索引中的列的子集,出于相同的原因,查询处理器也必须获取存储在该索引中的 每一 列,而不仅是请求的列,出于相同的原因-所有I /O必须在页,索引数据就像表数据一样存储在IO页中。因此,如果您为索引页定义“元组”作为存储在索引中的一组列,则该语句仍然为true。 该语句在美学上是正确的,因为重点是它基于I / O页中存储的内容而不是您要的内容来获取数据,并且无论您是访问基表I / O页还是索引均是如此。 I / O页面。