为什么单列选择和多列选择之间存在性能差异

时间:2014-09-04 09:40:57

标签: mysql sql sql-server database postgresql

我有表格报告,其中有10列以上,其中除autoriccrement id之外的每个字段都是varchar。 任何表行的最大大小约为80000字节。

我观察到下面两个查询之间存在相当大的差异,其中服务器和客户端都位于同一系统上(行数约为1.5M)(列名也有索引)

select * from Report;

&安培;

select name from Report;

我经历了其他stackoverflow问题,其中Ans建议

  

“选择特定列更好的一个原因是它   提高了SQL Server可以访问数据的概率   索引而不是查询表数据。 “

我的问题是:

1)即使使用索引我们需要从实际的DB(即磁盘)读取,因此相同的磁盘I / O将会 在我们选择单列或多列时执行(假设使用*)。

2)有人可以用很少的内部解释为什么单列选择和多列选择之间存在差异。 据我所知,数据库尝试将完整的行存储在同一磁盘扇区中。

对于像

这样的用户表的某些查询,请说
select first_name from user & 
select first_name, age from user 

3)DB是否执行相同的磁盘I / O(对于上述查询),或者磁盘I / O可能不同,如果User表有10列以上,我们选择5~8列仍然磁盘I / O仍然存在相同?

已经在其他Ans中读过,使用select *不是优选的,它可能会导致视图和维护问题(向DB添加新列时的情况)

这可能是一个愚蠢的问题,因为仍在学习数据库(新手到主题)。如果某些问题已在任何地方得到解答,请提供链接。

3 个答案:

答案 0 :(得分:4)

你的假设是错误的。如果索引包含所有选定的列,则SQL Server不会访问磁盘以获取它们,它将从索引数据中检索它们。索引比数据页更可能保留在内存中,因此查询可能根本不必访问磁盘。

如果您的select包含您不需要但未包含在任何索引中的列,则服务器必须无缘无故地从磁盘读取数据。

另一件确实发生变化的事情是网络I / O.生产服务器可能必须每分钟为数百个客户端提供数千个查询。在数据中包含无用列会影响所有客户端。如果您考虑在流行网站中使用的服务器,客户端可能有几千台,情况会更糟。

答案 1 :(得分:1)

一个可能的答案是,如果需要的数据在索引中,MySQL将不会费心阅读该表。如果将name编入索引,则可能有意义。

Anpther只是传输结果所需的时间,这可能很重要,具体取决于您的设置/网络速度等。

答案 2 :(得分:1)

问题是TOAST

长数据值可以使这些值从行的其余部分压缩和/或存储。这称为TOAST。

如果您请求已经TOASTED的数据值,则数据库必须停止获取并解压缩它,这需要时间。

另一方面,如果您不选择不需要的列,则不必获取这些值。因为最大值现在是不合时宜的,所以行的主要部分包装更紧密,缓存更好,性能更好。

一般来说,最大值也是最不需要的值,所以这通常是一个很好的权衡。

故事的寓意是当性能对您很重要时,不要求您不需要的列,特别是当这些列可能具有较大的值时。

PostgreSQL确实只有索引扫描,但除非表中的每一列都包含在一个索引中,否则无法进行仅索引扫描以支持select *,因此不是这里的解释。