表中的列数是否会影响在没有索引的表上执行count(*)查询的性能?

6 浏览
0 Comments

表中的列数是否会影响在没有索引的表上执行count(*)查询的性能?

我正在创建基准表来测量我们的Netezza数据库的每小时负载(查询延迟,查询持续时间)。我对表中想要的行数有一个大致的想法,现在正在决定列数。表中不会有索引,我将运行全表扫描。

我正在尝试决定基准表需要多少列,并有以下问题:列数(及其类型)如何影响count(*)查询的性能。我最初的想法是,具有更多列的表将分布在更多的磁盘块上。因此,系统将不得不进行更多的磁盘搜索,导致查询时间更长。

虽然我正在使用Netezza,但我也欢迎与其他系统(如MySQL,Postgres,Vertica等)相关的答案,以帮助我更好地理解。

关于列数对查询性能的影响已经有过几次讨论(Q1Q2Q3)。这些问题讨论的是一般查询,而不是没有索引的全表扫描。因此,我提出了这个单独的问题。

0
0 Comments

表中的列数会间接影响性能。列中的数据也会影响速度。每个DBMS将行存储在块中,通常为8k块,但不一定。特别是数据仓库系统倾向于使用更大的块大小。如果一个表有很多包含大量数据(比如varchar列)的列,这意味着在一个单一的数据库块上可以放置更少的行。

对于支持适当隔离的事务系统,count(*)查询必须查询表中的所有行(并检查每一行是否对你的事务可见)。DBMS从硬盘读取的最小单位是块。因此,越多的行适合一个块,需要执行的I/O操作就越少。

如果一行平均占用100个字节,那么一个块大约包含80行。要统计一个包含80行的表的所有行,数据库只需要进行一次I/O操作(实际上还要进行一些查找表本身的操作)。

现在,如果每行需要1000个字节,一个块只包含大约8行,这意味着要统计所有行,DB需要执行8次I/O操作。

即使数据被缓存,仍然是1个“逻辑”I/O操作与8个“逻辑”I/O操作。

上述只适用于没有涉及索引的情况。

任何支持详细执行计划的DBMS都可以观察到这种效果。以Postgres为例,创建两个包含各自10万行的表。一个表有5列,另一个表有10列。通过执行explain analyze命令,可以得到查询的执行计划和I/O操作次数。可以观察到对于表中列数较多的情况,I/O操作次数更多。

类似的情况也可以在Oracle的SQL*Plus中观察到,通过设置set autotrace statistics选项可以显示执行过的(逻辑)I/O次数。

所以,表中的列数会影响count(*)查询的性能,较多的列会导致更多的I/O操作。

0