|
|
1
22
它总是拉一个元组(除了表被垂直分割成列段的情况),所以,为了回答您提出的问题,从性能的角度来看并不重要。但是,由于许多其他原因,(下面)您应该始终按名称具体选择所需的列。 它总是拉一个元组,因为(在我熟悉的每个供应商RDBMS中,所有内容(包括表数据)的底层磁盘上存储结构都是基于定义的 输入输出页面 (例如,在SQL Server中,每页为8千字节。每次读写I/O都是按页进行的。即,每次写入或读取都是完整的数据页。
由于这种底层的结构约束,结果是数据库中的每一行数据必须始终位于一个且只有一个页面上。它不能跨越多个数据页(除了像blobs这样的特殊情况,实际的blob数据存储在单独的页面块中,而实际的表行列则只获取一个指针…)。但这些例外只是例外,通常不适用,除非在特殊情况下(对于特殊类型的数据,或针对特殊情况的某些优化)。
例外。唯一的地方
编辑:要处理@mike sherer comment,是的,这是真的,从技术上讲,对您的特殊情况有一点定义,从美学上来说。首先,即使请求的列集是存储在某个索引中的列的子集,查询处理器也必须获取
每一个
存储在该索引中的列,而不仅仅是请求的列,原因相同-所有I/O都必须在页中完成,索引数据与表数据一样存储在IO页中。因此,如果将索引页的“tuple”定义为存储在索引中的一组列,那么该语句仍然为true。
出于其他原因不使用
|
|
|
2
102
你永远(永远)不应该使用的原因有很多
是的,最初需要更多的输入(工具如 SQL Prompt 因为SQL Server甚至可以帮助您实现这一点),但实际上有一个规则没有任何例外:不要在生产代码中使用select*。 曾经。 |
|
|
3
19
你应该
总是
只有
[编辑]:表示访问。愚蠢的大脑还在苏醒。 |
|
|
4
7
除非您存储的是大型Blob,否则性能不是问题。不使用select*的主要原因是,如果您将返回的行用作元组,那么列将按模式指定的顺序返回,如果这样做了更改,则必须修复所有代码。 另一方面,如果您使用字典样式的访问,那么列返回的顺序无关紧要,因为您总是按名称访问它们。 |
|
|
5
6
这立刻让我想到一个我正在使用的表,其中包含一个类型为的列
不用说我没有
但是,我承认我通常查询表中的所有列。 |
|
|
6
6
在SQL select期间,无论是select*还是select a、b、c,db都将引用表的元数据。为什么?因为这就是系统上表的结构和布局信息所在的位置。 它必须阅读此信息有两个原因。第一,简单地编译语句。它需要确保至少指定一个现有的表。此外,自上次执行语句以来,数据库结构可能已更改。 现在,显然,DB元数据被缓存在系统中,但它仍然需要进行处理。 接下来,元数据用于生成查询计划。每次编译语句时也会发生这种情况。同样,这是针对缓存的元数据运行的,但始终是这样。 只有在数据库使用预编译查询或缓存了前一个查询时,才会不执行此处理。这是使用绑定参数而不是文字SQL的参数。”select*from table where key=1”与“select*from table where key=?”是不同的查询。“1”在呼叫时绑定。 DBS主要依靠页面缓存来完成这项工作。许多现代数据库都很小,可以完全存储在内存中(或者,也许我应该说,现代内存足够大,可以容纳许多数据库)。然后,后端的主要I/O成本是日志记录和页面刷新。 但是,如果您仍在为数据库访问磁盘,那么许多系统所做的主要优化就是依赖索引中的数据,而不是表本身。 如果你有:
然后,如果您执行“select id,name from customer where id=1”,那么数据库很可能会从索引中而不是从表中提取这些数据。 为什么?它很可能会使用索引来满足查询(与表扫描相比),即使在WHERE子句中没有使用'name',该索引仍然是查询的最佳选项。 现在数据库拥有了满足查询所需的所有数据,因此没有理由自己访问表页。使用索引可以减少磁盘流量,因为与表相比,索引中的行密度更高。 这是一些数据库所使用的特定优化技术的手工波浪式解释。许多人有几种优化和调优技术。 最后,select*对于您必须手工输入的动态查询很有用,我从不将其用于“真正的代码”。单个列的标识为数据库提供了更多信息,可用于优化查询,并使您更好地控制代码中的模式更改等。 |
|
|
7
4
我认为没有确切的答案来回答你的问题,因为你在考虑性能和维护你的应用程序的便利性。
|
|
|
8
3
这里接受的答案是错误的。我遇到这个的时候 another question 作为这个问题的副本关闭(当我还在写我的答案-grr-因此下面的SQL引用了另一个问题)。 您应该始终使用select attribute、attribute…。不选择* 主要针对性能问题。
不是一个很有用的例子。请考虑:
如果(姓名、电话)上有索引,则无需从表中查找相关值即可解决查询-有一个 覆盖 索引。 此外,假设该表有一个包含用户图片的blob、一个上载的cv和一个电子表格… 使用select*将把所有这些信息拉回到DBMS缓冲区(从缓存中强制输出其他有用的信息)。然后,它将全部发送给客户机,用掉网络上的空闲时间和客户机上的内存来获取冗余的数据。 如果客户机以枚举数组的形式检索数据(如php的mysql-fetch-au数组($x,mysql-num)),也可能导致功能问题。也许当代码被写下时,“电话”是select*返回的第三列,但随后有人过来决定在“电话”前面的表格中添加一个电子邮件地址。所需字段现在移到第4列。 |
|
9
2
有理由这样做。我在postgresql上使用select*是因为在postgresql中,select*有很多事情是不能用显式的列列表来做的,特别是在存储过程中。同样,在Informix中,在继承的表树上选择*可以为您提供交错行,而显式列列表则不能,因为子表中的其他列也会返回。 我在PostgreSQL中这样做的主要原因是它确保我得到一个特定于表的格式良好的类型。这允许我获取结果并将它们作为PostgreSQL中的表类型。这也允许在查询中使用比刚性列列表更多的选项。 另一方面,刚性列列表提供了一个应用程序级别的检查,以确保DB模式没有以某些方式发生更改,这可能会有所帮助。(我在另一个层次上进行这种检查。) 至于性能,我倾向于使用视图和返回类型的存储过程(然后是存储过程中的列列表)。这使我能够控制返回的类型。 但请记住,我使用select*通常是针对抽象层,而不是针对基表。 |
|
|
10
2
Reference taken from this article: 无选择*: 当您使用_157;select*_157;时,您正在从数据库中选择更多的列,其中一些列可能不会被您的应用程序使用。 这将在数据库系统上产生额外的成本和负载,并在网络上传输更多的数据。 用选择*: 如果您有特殊的需求,并且在添加或删除列时创建了动态环境,则由应用程序代码自动处理。在这种特殊情况下,您不需要更改应用程序和数据库代码,这将自动影响生产环境。在这种情况下,可以使用__select*__。 |
|
|
11
0
只是在这里我没有看到的讨论中添加一个细微的差别:在I/O方面,如果您使用的是 column-oriented storage 如果只查询某些列,则可以减少很多I/O操作。当我们转向SSD时,与面向行的存储相比,好处可能要小一些,但有a)只读取包含您关心的列的块b)压缩,这通常会大大减小磁盘上数据的大小,从而减少从磁盘读取的数据量。 如果您不熟悉面向列的存储,Postgres的一个实现来自citus数据,另一个实现来自greenplum,另一个paraccel,另一个(不严格地说)是AmazonRedshift。对于mysql来说,有infobright,现在已经接近灭绝的infinidb。其他商业产品包括HP的Vertica、Sybase IQ、Teradata… |
|
|
12
-1
平等的
|
|
Sweepy Dodo · JSON lite的格式化 1 年前 |
|
|
giantjenga · 优化整数向量到二进制向量的转换 1 年前 |
|
Zegarek · Postgresql递归查询未提供预期结果 1 年前 |
|
|
Joe · 为什么这两个查询之间的性能存在如此大的差异? 2 年前 |
|
tic-toc-choc · 在`dplyr中高效使用列表进行过滤` 2 年前 |