mysql - MySQL GROUP BY 是否不必要地使用 Temporary?
问题描述
我正在尝试优化查询。使用EXPLAIN
告诉我它是Using temporary
. 考虑到表的大小(20m+ 记录),这确实是低效的。查看 MySQL 文档Internal Temporary Tables我没有看到任何暗示我的查询中需要临时表的内容。我还尝试将 ORDER BY 设置为与 GROUP BY 相同,但仍然说使用临时和查询需要永远运行。我正在使用 MySQL 5.7。
有没有办法避免为此查询使用临时表:
SELECT url,count(*) as sum
FROM `digital_pageviews` as `dp`
WHERE `publisher_uuid` = '8b83120e-3e19-4c34-8556-7b710bd7b812'
GROUP BY url
ORDER BY NULL;
这是我的表架构:
create table digital_pageviews
(
id int unsigned auto_increment
primary key,
visitor_uuid char(36) null,
publisher_uuid char(36) default '' not null,
property_uuid char(36) null,
ip_address char(15) not null,
referrer text null,
url_delete text null,
url varchar(255) null,
url_tmp varchar(255) null,
meta text null,
date_created timestamp not null,
date_updated timestamp null
)
collate = utf8_unicode_ci;
create index digital_pageviews_url_index
on digital_pageviews (url);
create index ndx_date_created
on digital_pageviews (date_created);
create index ndx_property_uuid
on digital_pageviews (property_uuid);
create index ndx_publisher_uuid
on digital_pageviews (publisher_uuid);
create index ndx_visitor_uuid_page
on digital_pageviews (visitor_uuid);
解决方案
它需要一个临时表的原因是它不能同时publisher_uuid
对没有索引的列进行过滤和排序。第一步是过滤publisher_uuid
,所以它使用索引publisher_uuid
。
但是,接下来它必须对记录进行分组和排序,这将需要一个临时表,因为它不能使用执行此操作的索引。它不能使用索引的原因是它已经使用了publisher_uuid
,它没有在url
字段上建立索引以进行分组或在您订购的字段上。
要过滤 where publisher_uuid = '8b83120e-3e19-4c34-8556-7b710bd7b812'
、 group byurl
和 order by url
,请按以下顺序使用这些字段创建索引:
- 发布者_uuid
- 网址
create index ndx_publisher_uuid
on digital_pageviews (publisher_uuid, url);
推荐阅读
- apache-kafka-streams - Kafka Streams 是否可以使用一种格式的消息并生成另一种格式,例如 AVRO 消息
- c# - 每两秒发出 100 个并发 HTTP 请求,第一批需要的时间比其余的要多得多
- r-markdown - 我想要数字之间的文字,但它显示数字上方的文字
- xaml - Xamarin - 如何查看呈现的 Xaml
- go - 在等待上下文取消时执行代码
- java - Timestamp.valueOf 返回错误值
- php - 即使使用 SQLite3::escapeString() 并且不询问用户输入,SQL 注入漏洞?
- html - 传单地图未填充整个包装 div
- c# - 在 C# 中访问字符串的一部分
- reactjs - 如何在 package.json 脚本中重用从 build 命令设置的 .env 文件变量