2015-03-31 62 views
1

我听说手动选择柱(“col1,col2,col3等”)而不是用“*”查询它们会更快。只查询特定列是否更快?

但是如果我甚至不想查询表的所有列呢?例如,查询“col1,col2,col3,col4”的“col1,col2”insteaf是否会更快?

从我的理解来看,SQL无论如何都要搜索所有列,而只是返回结果的变化。我想知道我是否可以通过选择正确的栏目来获得业绩增长。

(我反正这样做,但我的应用程序之一的后端API返回往往不是所有列,所以我正在考虑让用户手动选择他想要的列)

回答

6

在一般来说,减少select中的列数是次要的优化。这意味着从数据库服务器向调用服务器的应用程序返回的数据更少。较少的数据通常更快。

在大多数情况下,这是一个小小的改进。在某些情况下,改进可能更加重要:

  • 如果覆盖索引可用于查询,则索引满足查询而不必访问数据页面。
  • 如果某些字段很长,则记录占用多个页面。
  • 如果正在检索的数据量是每个记录中整体数据的一小部分(认为是10%)。

单独列出列是一个不错的主意,因为它可以保护代码免受基础模式的更改。例如,如果列的名称发生更改,那么明确列出列的查询将以易于理解的错误中断。这比运行并产生错误结果的查询要好。

+0

很好的答案。我的查询检索大型二进制(图像),所以当我不需要图像时列出其他列将是一个更好的主意,是吗? – user1019042 2017-04-09 21:30:08

2

您应该尽量不要使用select *

  • 将数据传输给消费者的效率低下。当你选择*时,你经常从数据库中检索出比你的应用程序真正需要的更多列。这会导致更多数据从数据库服务器迁移到客户端,从而减慢访问速度并增加您的计算机负载,并且花费更多时间在网络上传输。当有人向不存在的基础表添加新列并且当原始消费者对其数据访问进行编码时不需要这些列时,情况尤其如此。

  • 索引问题。考虑一种您想调整查询以获得高级性能的场景。如果您要使用*,并且它返回的列数比实际需要的多,则服务器通常必须执行比其他方式更昂贵的方法来检索数据。例如,你将无法创建一个简单覆盖SELECT列表中的列的索引,即使你做了(包括所有列[shudder]),下一个出现并添加了列的人基础表会导致优化器忽略优化的覆盖索引,并且您可能会发现查询的性能会显着下降,因为没有明显的原因。

  • 绑定问题。当您选择*时,可以从两个不同的表中检索两个同名的列。这通常会导致数据使用者崩溃。想象一下连接两个表的查询,它们都包含一个名为“ID”的列。消费者如何知道哪个是哪个?当基础表结构发生变化时,SELECT *也会混淆视图(至少在某些版本的SQL Server中) - the view is not rebuilt, and the data which comes back can be nonsense。其中最糟糕的部分是你可以随心所欲地列出你想要的列名,但下一个出现的人可能无法知道他不得不担心添加一列会与你已经开发的列相冲突名。

我从this得到了答案。

1

所有的列标签和值占据一定的空间。将它们发送到请求的发布者而不是列的子集意味着发送更多数据。更多数据发送较慢。

如果你有列,像 idusernamepasswordemailbiourl

,你想只得到usernamepassword,然后

select username, password ... 

是快于

select * ... 

,因为id,email,biourl也发送给后者,这会使响应变大。但select *的主要问题是不同的。如果由于某种原因列的顺序改变了,它可能是不一致的根源。另外,它可能检索你不想检索的数据。将白名单与实际想要检索的列放在一起比较好。