如何解决MariaDB数据透视表的性能 执行计划:
我有一个表,其中包含具有动态类别的数据:
+----------+--------------+---------------+---------+
| category | string_value | integer_value | user_id |
+----------+--------------+---------------+---------+
| cat_1 | NULL | 1 | 1 |
| cat_1 | NULL | 3 | 2 |
| cat_2 | foo | NULL | 1 |
| cat_2 | bar | NULL | 2 |
+----------+--------------+---------------+---------+
我需要此表的透视表版本,该表可以与statement一起使用:
select
user_id,max(case when category == 'cat_1' then integer_value end) as 'cat_1',max(case when category == 'cat_2' then string_value end) as 'cat_2',from my_table
group by user_id
这将以以下格式创建结果:
+---------+-------+-------+
| user_id | cat_1 | cat_2 |
+---------+-------+-------+
| 1 | 1 | foo |
| 2 | 3 | bar |
+---------+-------+-------+
对于许多类别和表条目,此查询本身也表现良好(例如,对于8个类别和240k条目,大约需要20毫秒),但是如果我将此精确查询包装在select * from <query>
中,性能会下降显着(至650ms)。
此外,通过user_id
进行排序不会显着影响性能,而通过任何其他字段进行排序也会导致性能下降,即使相应字段和user_id
的索引存在。我猜想这种方法本身不适用于较大的表?
但是,我很好奇在添加select * from <query
部分时是什么导致了额外的执行时间。
背景:我尝试使用此查询存储动态用户数据,并且我想防止在运行时更改表结构(即添加列)。任何替代方案都将受到欢迎。我正在使用MariaDB 10.5.5,并且我需要该解决方案才能与MySQL 5.7和SQL Server 2019一起使用。
执行计划:
没有select * from
周围:
+----+-------------+-----------+-------+---------------+------------+---------+-----+--------+---------+----------+------------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | r_rows | filtered | r_filtered | Extra |
|----|-------------|-----------|-------|---------------|------------|---------|-----|--------|---------|----------|------------|-------|
| 1 | SIMPLE | user_data | index | | user_index | | 9 | 226067 | 1619.00 | 100.0 | 99.88 | |
+----+-------------+-----------+-------+---------------+------------+---------+-----+--------+---------+----------+------------+-------+
周围有select * from
:
+----+-------------+------------+-------+---------------+------------+---------+-----+--------+-----------+----------+------------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | r_rows | filtered | r_filtered | Extra |
|----|-------------|------------|-------|---------------|------------|---------|-----|--------|-----------|----------|------------|-------|
| 1 | PRIMARY | <derived2> | ALL | | | | | 226067 | 200.00 | 100.0 | 100.0 | |
| 2 | DERIVED | user_data | index | | user_index | 9 | | 226067 | 242418.00 | 100.0 | 100.0 | |
+----+-------------+------------+-------+---------------+------------+---------+-----+--------+-----------+----------+------------+-------+
解决方法
这是我对正在发生的事情的猜测。
您在基础表上有一个索引,MariaDB使用该索引进行聚合。这意味着没有排序。 。 。只需读取索引,它就可以开始返回行。
这是一个非常好的功能。但是,当您只运行查询时,您看到的是第一行的时间。
使用派生表时,MariaDB必须先生成 all 行,然后再返回其中的 any 条。因此,带有子查询的select *
要做的工作更多。
这就是为什么第二个版本比第一个版本慢的原因。我希望在大多数计算机上返回数万行的查询花费20毫秒以上的时间。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。