回答

收藏

使用COUNT(*)或SELECT *是个好主意吗?

技术问答 技术问答 95 人阅读 | 0 人回复 | 2023-09-13

我多次听说你不应该执行COUNT(*)或SELECT *考虑到性能,但无法深入了解其更多信息。
0 _7 E* }: K. W- b( s/ p我可以想象数据库随后会 所有    列用于操作,可能导致性能下降,但我不确定。有人对这个主题有更多的信息吗?6 A+ A5 O( b  y/ u6 N
                                                               
& B# [8 u% f- v7 Z8 Z) K! X. [    解决方案:                                                                & b; {7 K# ~5 C* M& M
                                                                1.关于count(*)vs. count(其他)SQL它是声明性的,你可以指定所需的 内容    。这与指定 不同如何1 `. p. b( K- M  V4 s5 p
得到你需要的东西。这意味着数据库引擎可以有效的方式自由实现您的查询。许多数据库优化器将您的查询重写为低成本的替代方法(如果有这样的计划)。% Y# z6 _" K  r  R3 T/ k
给出下表:- C; a: }# R3 |+ c+ m% g  h
table(   pk       not null  ,color    not null  ,nullable null  ,unique(pk)  ,index(color));…以下 所有    功能等效(因为 count    和 null的机制    ):: c3 }! L  [8 q0 h; p* w. x
1) select count(*) from table;2) select count(1) from table;3) select count(pk) from table;4) select count(color) from table;无论使用哪种形式,优化器都可以自由地将查询重写为另一种形式(如果更有效)。(同样,并非所有的优化器都足够复杂)。唯一的索引(pk)它将小于整个表(占用的字节数)。因此,计算索引条目的数量比扫描整个表更有效。Oracle在中间,我们有一个图形索引,它还压缩了重复的字符串。如果我们在颜色列上使用这样的索引,它可能是扫描的最小索引。Oracle在某些情况下,它还支持表压缩,使物理表小于复合索引。) u4 d' g/ r5 w9 V# {
1. TL; DR;# G, X! s* J$ G
您的特定dbms将有自己的工具集,可以使用不同的重写规则并执行计划。这使得这个问题毫无用处(除非我们谈论特定的事情dbms具体发行版)。我建议。COUNT(*)它在所有情况下都被使用,因为它需要最少的认知努力。
! W: ~9 m, ?, W3 U% [& B3 Q2.在选择a,b,c与选择*您*    编写并投入生产SELECT*代码很少有效。想象一下包含在内的Bluray电影表(是的,这些电影存储在表中blob)。因此,您将您的真棒酱抽象层拍打在一起,并将其放入此方法中。我不会解释为什么它以更快的速度跨网络传输。当然,在大多数实际情况下,它不会产生明显的影响。. b7 [: e4 L  a' n& ^7 S8 \
*SELECT * FROM movies where id = ?``getMovies(movie_id)``SELECT name FROMmovies
: B4 [7 I* t3 A% W5 P关于性能的最后一点是,当查询中引用的所有列(选择和过滤)都作为索引(称为覆盖索引)存在时,数据库根本不需要触摸表。仅扫描索引就可以完全解决这个问题。该选项可以从优化器中删除,以选择所有列。
) t. p7 d$ \# U  ]) o1 W2 C另一个SELECT *比什么都严重的是,它对表的具体物理布局有隐藏的依赖。让我解释一下。请考虑以下表格:
$ A; m' A# `8 F# B' J& O8 W- P" Z% btable T1(name,id)table T2(name,id)以下声明…$ v# G" V( ~) K& I, v
insert into t1 select * from t2;若发生以下情况,将打破或产生不同的结果:$ O& N  I* `5 G
例如,表中的任何会重新排列,例如T1(id,name)
6 o$ e, `/ d4 @& s* {T1获得额外的非空列
, @4 N5 d+ E- o$ W6 y: ^T2进入另一列
2. TL; DR;0 D! Y# N: \1 K
在可能的情况下,明确指定所需的列(最后,必须这样做)。同样,选择更少的列比选择更多的列更快。显式选择的一个可能的副作用是,它为优化器提供了更大的自由。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则