如果我有一个100列的表Application_user,两个查询之间的性能差异是什么:
查询一:
第一个月
查询二:
select a.col1.a.col2,a.col3........ from Application_user a;个两个查询之间的性能差异及其背后的原因
select a.col1.a.col2,a.col3........ from Application_user a;
jv4diomz1#
关于Oracle:有时候SELECT COUNT(*) from ..的计算速度比SELECT COUNT(1) from ...慢。Oracle必须执行额外的查找以将'*'转换到列列表中,然后丢弃此信息。如果SELECT *和SELECT col1, col2, ...之间存在任何性能差异,那么这些差异几乎无法衡量。另外,SELECT *是已知的SQL反模式。它不提供稳定的接口,并且添加列会破坏尚未准备好处理它的应用程序。此外,在极少数情况下,如果您返回的列数超过必要的列数,则高频查询可能会返回超过网络适配器带宽或应用服务器端GC内存限制的大结果集。
SELECT COUNT(*) from ..
SELECT COUNT(1) from ...
SELECT *
SELECT col1, col2, ...
bbmckpt72#
其他人已经充分评论了SELECT *的代码破坏危险。然而,由于您的问题涉及性能,因此正确的答案存在一些细微差别。1.如果您使用的是Exhibition或其他支持混合列压缩(HCC)的工程系统,则选择的列数超过实际需要将对性能产生负面影响,因为它会阻止列投影减少返回数据库服务器的I/O,并且从列存储的数据重新组装行会产生成本。1.如果你的table太宽(超过254列或行超过块大小),结果产生了链接,从列列表的右端选择列,其中它可能被断开到不同的块,这将导致单个块的急剧性能损失,如果你只需要几个列,并且它们在原始块中,最好列出所需的列,这样额外的块阅读可以避免。1.如果表中的列中有您不需要的LOB,那么不必要地提取它们将增加大量您不需要的额外处理。1.如果你是通过网络获取结果,那么你拉的列越多,你将招致更多的网络开销。1.如果你有一个连接的一个包含查询真正需要的所有列的(多列)索引,你可以潜在地避免完全命中表。同样,几个集合了你需要的所有列的索引也可以通过连接在一起来避免命中表。但是如果你使用*,除非索引包含表中的每一列,您将不符合这些可能的优化器技巧,因此,您可能会在性能上受到影响。因此,只列出实际需要的列而不是懒惰和默认为*有许多性能考虑。然而,所有上述仅适用于您不需要所有列的情况。如果您需要所有列,那么单独指定它们和使用*之间没有性能差异。无论哪种方式,Oracle都必须在字典中查找列。所以,不要使用select *。这是一个方便的时间节省表的临时探索,但不应该在代码中使用。一个例外,它是刚刚好是在一个EXISTS子查询:WHERE EXISTS (SELECT * ....)。Oracle知道在这种情况下您实际上不需要任何列,并且实际上不会尝试访问任何列,只是确定行是否存在。它这样使用也不会弄坏任何东西。但在其他情况下我会避免这样做。
*
select *
EXISTS
WHERE EXISTS (SELECT * ....)
nzkunb0c3#
MySQL...这个问题并不精确,第二个公式是否包括所有的列?如果它包含了所有的列,那么就没有明显的 * 性能 * 差异(*转换为第二种公式,但是*需要一点点网络传输时间)。如果第二个缺少一些列,那么如果省略的列是TEXT或BLOB,那么它 * 可能 * 可能会有很大的差异。而且,是的,“最佳实践”说不要使用*。
TEXT
BLOB
3条答案
按热度按时间jv4diomz1#
关于Oracle:
有时候
SELECT COUNT(*) from ..
的计算速度比SELECT COUNT(1) from ...
慢。Oracle必须执行额外的查找以将'*'转换到列列表中,然后丢弃此信息。如果
SELECT *
和SELECT col1, col2, ...
之间存在任何性能差异,那么这些差异几乎无法衡量。另外,
SELECT *
是已知的SQL反模式。它不提供稳定的接口,并且添加列会破坏尚未准备好处理它的应用程序。此外,在极少数情况下,如果您返回的列数超过必要的列数,则高频查询可能会返回超过网络适配器带宽或应用服务器端GC内存限制的大结果集。
bbmckpt72#
其他人已经充分评论了
SELECT *
的代码破坏危险。然而,由于您的问题涉及性能,因此正确的答案存在一些细微差别。1.如果您使用的是Exhibition或其他支持混合列压缩(HCC)的工程系统,则选择的列数超过实际需要将对性能产生负面影响,因为它会阻止列投影减少返回数据库服务器的I/O,并且从列存储的数据重新组装行会产生成本。
1.如果你的table太宽(超过254列或行超过块大小),结果产生了链接,从列列表的右端选择列,其中它可能被断开到不同的块,这将导致单个块的急剧性能损失,如果你只需要几个列,并且它们在原始块中,最好列出所需的列,这样额外的块阅读可以避免。
1.如果表中的列中有您不需要的LOB,那么不必要地提取它们将增加大量您不需要的额外处理。
1.如果你是通过网络获取结果,那么你拉的列越多,你将招致更多的网络开销。
1.如果你有一个连接的一个包含查询真正需要的所有列的(多列)索引,你可以潜在地避免完全命中表。同样,几个集合了你需要的所有列的索引也可以通过连接在一起来避免命中表。但是如果你使用
*
,除非索引包含表中的每一列,您将不符合这些可能的优化器技巧,因此,您可能会在性能上受到影响。因此,只列出实际需要的列而不是懒惰和默认为
*
有许多性能考虑。然而,所有上述仅适用于您不需要所有列的情况。如果您需要所有列,那么单独指定它们和使用*
之间没有性能差异。无论哪种方式,Oracle都必须在字典中查找列。所以,不要使用
select *
。这是一个方便的时间节省表的临时探索,但不应该在代码中使用。一个例外,它是刚刚好是在一个EXISTS
子查询:WHERE EXISTS (SELECT * ....)
。Oracle知道在这种情况下您实际上不需要任何列,并且实际上不会尝试访问任何列,只是确定行是否存在。它这样使用也不会弄坏任何东西。但在其他情况下我会避免这样做。nzkunb0c3#
MySQL...
这个问题并不精确,第二个公式是否包括所有的列?
如果它包含了所有的列,那么就没有明显的 * 性能 * 差异(
*
转换为第二种公式,但是*
需要一点点网络传输时间)。如果第二个缺少一些列,那么如果省略的列是
TEXT
或BLOB
,那么它 * 可能 * 可能会有很大的差异。而且,是的,“最佳实践”说不要使用
*
。