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

+------------+----------+------+-----+---------+----------------+
| 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;


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

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

评论

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

ORDER BY NUMBER语法很容易出错。

在最后一条注释中,SELECT *与ORDER BY中的列索引相结合会混淆正在排序的列-避免* s ...的另一个原因

@lc。,你是什么意思?

@Pacerier我的意思是*不是明确的。因此,说“给我所有列并按第三个列排序”与“去超市告诉我您通过了多少个交通信号灯”一样具有确定性。

#1 楼

短语ORDER BY 1指的是不同的列;第一个是id,第二个是val。由于id是键,因此将对其进行索引,而order by的工作量很小。但是,对于order by val,系统将必须检索每一行,按val排序完整的表,然后仅选择其中的一行。几乎相同。

评论


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

– dotancohen
2014年7月27日在12:33

#2 楼

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


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


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

评论


SELECT *即使对于单表查询也可能是一个问题。例如,SELECT * FROM hashs ORDER BY val;可能会进行全表扫描,然后在SELECT val FROM hash hash ORDER BY val时进行排序;将仅执行完整索引扫描,并且不进行任何排序(假设val上存在索引)。因此,只选择我们需要的结果就没有什么害处。

–超立方体ᵀᴹ
2014年7月28日在16:49



我想你已经看到了吗? sqlblog.com/blogs/aaron_bertrand/archive/2009/10/10/…

– Max Vernon♦
2014年7月28日在17:10

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

–起搏器
15年4月8日在18:20

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

–超立方体ᵀᴹ
2015年4月8日在22:11



@ypercube,嗯,只要它像pgsql一样聪明。

–起搏器
2015年4月9日下午5:05