+------------+----------+------+-----+---------+----------------+
| 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
操作。为什么更具体的查询要比
*
查询花费更长的时间?我一直认为应该出于性能原因而避免*
查询。#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
评论
第一条语句很可能使用id上的主键索引来查找第一行。第二个需要在(未索引的)val列上对完整结果进行排序。ORDER BY NUMBER语法很容易出错。
在最后一条注释中,SELECT *与ORDER BY中的列索引相结合会混淆正在排序的列-避免* s ...的另一个原因
@lc。,你是什么意思?
@Pacerier我的意思是*不是明确的。因此,说“给我所有列并按第三个列排序”与“去超市告诉我您通过了多少个交通信号灯”一样具有确定性。