我只是好奇。
假设您有一个包含 100 万条记录/行的表。
select order_value from store.orders
在实际查询时间中,该表是否有 1 个字段、2 个字段或 100 个字段有区别吗?我指的是“order_value”以外的所有字段。
现在我正在将数据推送到数据仓库。有时我将字段转储到表中“可能会在未来某一天使用”——但它们现在没有被任何东西查询。这些“无关”字段是否会直接或间接影响不包含它们的选择语句(不 * 我的意思是)?
我只是好奇。
假设您有一个包含 100 万条记录/行的表。
select order_value from store.orders
在实际查询时间中,该表是否有 1 个字段、2 个字段或 100 个字段有区别吗?我指的是“order_value”以外的所有字段。
现在我正在将数据推送到数据仓库。有时我将字段转储到表中“可能会在未来某一天使用”——但它们现在没有被任何东西查询。这些“无关”字段是否会直接或间接影响不包含它们的选择语句(不 * 我的意思是)?
这取决于表结构和可用索引。
案例 A:普通(行存储)表,没有索引
(order_value)
。唯一可能的执行计划是读取整个表(当它是 2 列和 200 列时,这当然有很大不同,所以几个字节和几千字节宽)。
情况 B:公用表,有一个索引
(order_value)
或包含该列的其他一些索引。现在有一个更好的计划,扫描整个索引(其中一个)——这当然比整个表要窄得多,就几个字节。如果表格有 2 列或 200 列,这就无关紧要了。仅扫描索引。
案例 C:这是一个列存储表。
顾名思义,这些表的结构是按列排列的,而不是按行排列的。不需要任何索引,表设计本身适合读取整列。
这实际上取决于索引和数据类型。
以 Stack Overflow 数据库为例,Users 表如下所示:
它在 Id 列上有一个 PK/CX。所以它是按 Id 排序的整个表数据。
有了它作为唯一的索引,SQL 必须将整个内容(没有 LOB 列)读入内存(如果它不在内存中)。
统计时间和 io 配置文件如下所示:
如果我在 Id 上添加一个额外的非聚集索引
我现在有一个小得多的索引来满足我的查询。
这里的个人资料:
我们能够进行更少的读取并节省一点 CPU 时间。
如果没有关于您的表定义的更多信息,我真的无法尝试更好地重现您要测量的内容。
是的,这是特定于行存储表的。数据按行存储在数据页上。即使页面上的其他数据与您的查询无关,整行 > 页面 > 索引也需要读入内存。我不会说其他列被“扫描”得如此之多,因为它们所在的页面被扫描以检索与查询相关的单个值。
使用 ol' 电话簿示例:即使您只是阅读电话号码,当您翻页时,您也会翻到姓氏、名字、地址等以及电话号码。