我有一个包含大约2200万行和大约20列包含属性数据的表。目前有一个类似的查询:
SELECT * FROM fulldataset WHERE county = 'MIDDLESBROUGH'
平均需要42秒才能运行。为了尝试改进这一点,我在县列上创建了一个索引,如下所示:
ALTER TABLE fulldataset ADD INDEX county (county)
同一查询的速度根本没有任何改善。
所以我使用EXPLAIN SELECT来试图找出发生了什么。如果我从countyA中选择SELECT *,它会在~42秒后返回大约85k个条目。如果我解析选择相同的查询它说它使用我创建的县索引,行数约为167k,这是错误的,但比搜索所有2200万更好。
同样,如果我为countyB选择SELECT *,我得到大约48k的结果,EXPLAIN SELECT告诉我有大约91k行。 EXPLAIN SELECT语句立即返回结果,因此它能够立即告知countyB的条目大约是countyA的一半。问题是查询执行得不快。如果它只检查91k行应该不是很快?
以下是我正在做的截图:image
编辑:正如所指出的那样,查询本身并不需要时间。在评论中回答我自己的问题时,多列索引创造了奇迹。
答案 0 :(得分:0)
查询不是问题。如果你仔细查看程序的输出,你会发现查询执行时间不到1秒,但是获取所有行需要花费42秒。
如果您在看到任何内容之前必须等待42秒,那么我建议您使用另一个查询工具,该工具仅获取前X行并将其显示在页面中。
答案 1 :(得分:0)
EXPLAIN
旨在加快速度。在这样做时,“行”的计算只是粗略的估计。如果经常可以关闭2倍。所以,不要读太多到85K对167K。
由于EXPLAIN
只提供一行(或少量行),因此“提取”时间非常短。
如果您选择某列的AVG()
,则必须首先读取所有相关行,然后按计算进行计算。在完成所有读数之前,它甚至无法开始传送数据。
如果您正在阅读所有行,它可以(但我不确定它是否)开始提供以第一行行开头的行。
如果您执行SELECT * FROM tbl ORDER BY x
之类的操作(并且x
未编入索引),那么您将获得最差或两个世界。 首先它必须读取所有行并将它们写入临时表,然后它对临时表进行排序;只有这样它才能开始来获取行。
我认为“持续时间”和“获取”不是很有用;两者的总和更有用。这是另一个例子:Mysql same querys one with index second without getting 10000xFetch time? 注意总和是如何一致的,但分离不是。