情况1:我有一个包含30列的表,我在where子句中使用4列进行查询.
情况2:我有一个包含6列的表,我在where子句中使用4列进行查询.
两种情况下的表现有何不同?
例如我有桌子
table A
{
b varchar(10),
c varchar(10),
d varchar(10),
e varchar(10),
f varchar(10),
g varchar(10),
h varchar(10)
}
SELECT b,c,d
FROM A
WHERE f='foo'
create table B
{
b varchar(10),
c varchar(10),
d varchar(10),
e varchar(10),
f varchar(10)
}
SELECT b,c,d
FROM B
WHERE f='foo'
Run Code Online (Sandbox Code Playgroud)
A和B表具有相同的结构意味着在条件也相同且列中的列也相同时使用的列数和列数的差异.不同之处在于表B只有一些未使用的列,这些列未在select中使用,在这种情况下,两种查询的性能有何不同?
Stu*_*tLC 12
表中的总列数是否会影响性能(如果选择了相同的列子集,并且表中没有索引)
是的,根本没有索引,两个查询(表A和表B)都将执行表扫描.鉴于Table B列数少于Table A,每页的行数(密度)将更高B,因此B需要获取的页面越少,因此速度会越快.
但是,鉴于您的查询形式如下:
SELECT b,c,d
FROM X
WHERE f='foo';
Run Code Online (Sandbox Code Playgroud)
查询的性能将由列上的索引控制f,而不是基础表中的列数.
对于这个确切的查询,最快的性能将来自以下索引:
A(f) INCLUDE (b,c,d)B(f) INCLUDE (b,c,d)在这两种情况下,两个查询的性能应该相同(假设两个表中的数据相同),因为SQL将命中现在具有相似列宽和行密度的索引,而不需要原始表中的任何其他数据.
select中的列数是否会影响查询性能?
在a中返回较少列的主要好处SELECT是SQL可能能够避免从表/集群中读取,而是,如果它可以selected从索引中检索所有数据(作为索引列和/或包含在列中的列)一个的覆盖索引).
显然,谓词中使用的列(在过滤器中),即f在您的示例中,必须在索引的索引列中,并且必须具有足够的选择性,以便首先使用索引.
从a返回较少的列还有一个第二个好处SELECT,因为这会减少任何I/O开销,特别是如果数据库服务器和使用数据的应用程序之间的网络速度很慢 - 也就是说好的做法只能返回您实际需要的列,并避免使用SELECT *.
编辑
其他一些计划:
B(f)没有其他键或INCLUDE列,或列不完整INCLUDE(即b, c or d缺少一个或多个):SQL Server可能需要进行密钥或RID 查找,因为即使使用索引,也需要"连接"回表以检索select子句中缺少的列.(查找类型取决于表是否具有聚簇PK)
B(f,b,c,d)这仍然是非常高效的,因为将使用索引并避免使用表,但不会像覆盖索引那样好,因为索引树的密度将因索引中的其他键列而更少.
测试一下,看看!
会有性能差异,但是在 99% 的情况下您不会注意到它 - 通常您甚至无法检测到它!
您甚至不能保证具有较少列的表会更快 - 如果它困扰您,请尝试并查看。
技术垃圾:(从微软SQL Server的角度来看)
假设在所有其他方面(索引、行数、包含在 6 个公共列中的数据等),这些表是相同的,那么唯一真正的区别将是更大的表分布在磁盘上的更多页面上/ 在记忆中。
SQL Server 只尝试读取它绝对需要的数据,但它总是一次加载整个页面 (8 KB)。即使需要与查询输出完全相同的数据量,如果该数据分布在更多页面上,则需要更多 IO。
也就是说,SQL Server 的数据访问效率非常高,因此除非在极端情况下,否则您不太可能看到对性能的显着影响。
此外,无论如何,您的查询也可能针对索引而不是表运行,因此对于完全相同大小的索引,更改可能是0。
| 归档时间: |
|
| 查看次数: |
15269 次 |
| 最近记录: |