Mysql 语句执行顺序疑问

凉凉二点凉 2018-05-07 06:24:03
有一张表,数据量很大,大概5G左右
现在有一个很简单的sql,类似下面的语句

SELECT
col_name, SUM(count) AS value
FROM
table_name
WHERE
sys_date BETWEEN '2017-10-01' AND '2017-10-31'
GROUP BY col_name
ORDER BY value DESC

是不是很简单,执行时间大概50秒
但是我换一种写法,先通过where得到一个结果集,然后在这结果集上做一次group by

SELECT col_name, SUM(count) AS value
FROM
(
SELECT
col_name, count
FROM
table_name
WHERE
sys_date BETWEEN '2017-10-01' AND '2017-10-31'
) A
GROUP BY col_name
ORDER BY value DESC

这样的执行结果只有4秒
为什么会是这样?

Group BY 不是作用在where的结果集上的吗?但是我感觉第一个sql的执行顺序并不是这样,不然,两个类似的SQL为什么差别这么大?

PS:
explain的结果没什么太大的差别,索引都没有用到
...全文
797 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
zjcxc 2018-05-08
  • 打赏
  • 举报
回复
第一个查询最后面多了一句 ORDER BY A.value DESC 你把第2个查询加上这个再测试一下
凉凉二点凉 2018-05-08
  • 打赏
  • 举报
回复
上面第一个SQL中11行多了两个括号
凉凉二点凉 2018-05-08
  • 打赏
  • 举报
回复
引用 7 楼 ACMAIN_CHM 的回复:
楼主的真实SQL语句是什么?
第一个SQL(慢)

EXPLAIN
SELECT	
	 	 A.execute_app AS name, IFNULL(category_mapping.view_name, execute_app) AS mappingName
FROM
	 (
SELECT		 	
		 	sys_date,
		 	month_number,
		 	execute_app, SUM(COUNT) AS value
FROM path_rule
WHERE month_number=10 AND YEAR = 2017)) AND execute_app IS NOT NULL AND LENGTH(execute_app) > 0
GROUP BY execute_app
ORDER BY value DESC)A
LEFT JOIN
			category_mapping ON 
			A.execute_app = category_mapping.log_name AND category_mapping.kpi_name = 'path_rule_app'
ORDER BY A.value DESC
LIMIT 10		
第二个SQL, group by 放外面的(快)

EXPLAIN
SELECT	
	 	 A.execute_app AS name, IFNULL(category_mapping.view_name, execute_app) AS mappingName
FROM
	 (
SELECT execute_app, SUM(COUNT) AS value
FROM(
SELECT execute_app, COUNT
FROM 
			path_rule
WHERE month_number = 10 AND YEAR = 2017 AND execute_app IS NOT NULL AND LENGTH(execute_app) > 0	) r
GROUP BY execute_app
ORDER BY value DESC)A
LEFT JOIN
			category_mapping ON 
			A.execute_app = category_mapping.log_name AND category_mapping.kpi_name = 'path_rule_app'
LIMIT 10		
		
Explain的结果上面贴过了
ACMAIN_CHM 2018-05-08
  • 打赏
  • 举报
回复
楼主的真实SQL语句是什么?
zjcxc 2018-05-08
  • 打赏
  • 举报
回复
条件列上没有索引 ? 对比执行计划,两个执行计划,一个走了索引,另一个没有,但是搜索的记录数都一样,所以第一个查询的索引应该不是条件上的索引 然后看执行计划的 Extra,不知道楼主用的什么版本,具体的查询和表结构是什么 按照你写的查询,只有一个条件,但里面 Extra 里面出现了两次 WHERE , 第一个查询还出现了两次 sort 正常的单表应该是一次 WHERE + 一次 SORT (我在 5.7 版本上,童瑶查询模拟验证了一下,两种写法执行计划一样,只会有一条执行计划)
zjcxc 2018-05-08
  • 打赏
  • 举报
回复
explain 对比下执行计划 如果 table_name 是表, 理论上这两个的执行计划应该是一样的, 如果是查询 VIEW,那另当别论 如果对比执行计划确定是一样的话,那么可能是缓存,你可以多次执行对比下效率
凉凉二点凉 2018-05-08
  • 打赏
  • 举报
回复
引用 1 楼 ACMAIN_CHM 的回复:
看一下EXPLAIN SELECT有什么不同。
这是第一个的explain

"id"	"select_type"	"table"	"type"	"possible_keys"	"key"	"key_len"	"ref"	"rows"	"Extra"
"1"	"PRIMARY"	"<derived2>"	"ALL"	\N	\N	\N	\N	"2576336"	"Using temporary; Using filesort"
"1"	"PRIMARY"	"category_mapping"	"ALL"	\N	\N	\N	\N	"148"	"Using where; Using join buffer (Block Nested Loop)"
"2"	"DERIVED"	"path_rule"	"index"	"INDEX_APPS,INDEX_APPS_WEEK"	"INDEX_APPS"	"306"	\N	"5152673"	"Using where; Using temporary; Using filesort"

这是第二个的

"id"	"select_type"	"table"	"type"	"possible_keys"	"key"	"key_len"	"ref"	"rows"	"Extra"
"1"	"PRIMARY"	"<derived2>"	"ALL"	\N	\N	\N	\N	"2576336"	\N
"1"	"PRIMARY"	"category_mapping"	"ALL"	\N	\N	\N	\N	"148"	"Using where; Using join buffer (Block Nested Loop)"
"2"	"DERIVED"	"<derived3>"	"ALL"	\N	\N	\N	\N	"2576336"	"Using temporary; Using filesort"
"3"	"DERIVED"	"path_rule"	"ALL"	"INDEX_APPS,INDEX_APPS_WEEK"	\N	\N	\N	"5152673"	"Using where"
xiaocongzhi 2018-05-08
  • 打赏
  • 举报
回复
缓存初次执行与执行几次效率会有很大差距 试试换一下顺序
AHUA1001 2018-05-08
  • 打赏
  • 举报
回复
第一个50秒,第二个4秒。 在执行完第二个以后,马上执行第一个看,看看需要多长时间。
爱吃火锅的S 2018-05-08
  • 打赏
  • 举报
回复
你第一个sql语句用了子查询,索引会失效,所以时间长
learn2020 2018-05-07
  • 打赏
  • 举报
回复
比较一下两个return的数据是否一样,然后看 explain select
oyljerry 2018-05-07
  • 打赏
  • 举报
回复
还是要仔细看看explain看有没有什么差别的地方没有发现
ACMAIN_CHM 2018-05-07
  • 打赏
  • 举报
回复
看一下EXPLAIN SELECT有什么不同。

56,685

社区成员

发帖
与我相关
我的任务
社区描述
MySQL相关内容讨论专区
社区管理员
  • MySQL
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧