为什么SELECT *比SELECT foo快很多?


28

考虑一个值和哈希表,如下所示:

+------------+----------+------+-----+---------+----------------+
| Field      | Type     | Null | Key | Default | Extra          |
+------------+----------+------+-----+---------+----------------+
| id         | int(11)  | NO   | PRI | NULL    | auto_increment |
| val        | char(9)  | NO   |     | NULL    |                |
| val_hashed | char(50) | YES  |     | NULL    |                |
+------------+----------+------+-----+---------+----------------+

以下查询在0.00秒内完成:

SELECT * FROM hashes ORDER BY 1 DESC LIMIT 1;

但是,此查询需要3分17秒:

SELECT val FROM hashes ORDER BY 1 DESC LIMIT 1;

我看到查询运行时,进程列表将其显示为status Sorting result。这种情况是完全可以重现的。请注意,还有另一个进程INSERT在表上连续执行操作。

为什么更具体的查询要比查询花费更长的时间*我一直认为*出于性能原因应避免查询。


7
前几条语句很可能使用主键索引on id来查找第一行。第二个需要在(未索引)val列上对完整结果进行排序。
a_horse_with_no_name 2014年

8
ORDER BY NUMBER语法是相当容易出错。
usr

2
添加到您的最后一条评论中,SELECT *再加上一个列索引,ORDER BY混淆了要对哪个列进行排序-避免出现以下问题*的另一个原因
lc。

@lc。,什么意思?
和平者

@Pacerier我的意思*是不明确。所以说:“给我所有的列和排序第三个”讲述的是确定性的话说:“去超市,并告诉了我很多的流量如何点亮你通过”
LC。

Answers:


33

该短语ORDER BY 1指的是不同的列;在第一个id,第二个val。既然id是关键,它将被索引,这order by将是一件微不足道的工作。要order by val,但是,系统将检索每一行,排序完整的表按val,然后选择只是那些行之一。

将两个查询都更改为order by id,我认为您的执行时间几乎相同。


3
有时最棘手的问题是那些正盯着我们的脸。谢谢,迈克尔!
dotancohen 2014年

7

MG很好地解释了查询中的性能差异。我要解决这个问题:

我一直认为*出于性能原因应该避免查询。

select *本身并没有特别的惩罚,如果滥用会产生问题。在单表查询中,它可以正常工作。现在将该表连接到具有20列的另一个表,然后将联接添加到其他5个表(每个表具有许多列)。现在,这是一个问题。那些教无用的创可贴“永不做X”的人也是如此。


3
SELECT *即使对于单表查询也可能是一个问题。例如,SELECT * FROM hashes ORDER BY val;可能会进行全表扫描,然后进行排序,而SELECT val FROM hashes ORDER BY val;仅进行完整索引扫描,而不进行排序(假设val上存在索引)。因此,仅选择我们需要的结果就不会造成伤害。
ypercubeᵀᴹ


@ypercube,即使我们select(*)仅用作选择,也会发生这种情况吗?由于它是嵌入式选择,因此MySQL是否足够聪明以找出需要选择的实际列?
Pacerier,2015年

@Pacerier mysql优化器具有不同级别的“智能”,具体取决于您使用的版本。在Gerneal中,关于嵌套子查询非常愚蠢,因此,只要您能帮助他,那都很好。
ypercubeᵀᴹ

@ypercube,嗯,只要它像pgsql一样聪明。
Pacerier,2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.