我正在尝试优化MySql中的视图。视图从表中获取0-5条记录并将其转换为1条记录。该视图有效,但随着property_log表中记录数的增加而减慢。
例如,数据如下所示:
mysql> select * from property_log where event_id = 1144882;
+----------+--------------+------------------------------+
| event_id | log_key | log_value |
+----------+--------------+------------------------------+
| 1144882 | userId | 1000 |
| 1144882 | licenseId | 3 |
| 1144882 | messageTypeId| 7 |
| 1144882 | message | Sample message |
| 1144882 | op | tracking |
+----------+--------------+------------------------------+
变成1条记录:
mysql> select * from view_logged_property where id = 1144882
+---------+--------+-----------+---------------+-------------------+
| ID | UserID | LicenseID | MessageTypeID | Message |
+---------+--------+-----------+---------------+-------------------+
| 1144882 | 1000 | 3 | 7 | Sample message |
+---------+--------+-----------+---------------+-------------------+
编辑:重要提示 - 并非所有5条记录都会一直存在。例如,数据也可能如下所示:
mysql> select * from property_log where event_id = 1144882;
+----------+--------------+------------------------------+
| event_id | log_key | log_value |
+----------+--------------+------------------------------+
| 1144882 | userId | 1000 |
| 1144882 | messageTypeId| 7 |
| 1144882 | message | Sample message |
| 1144882 | op | tracking |
+----------+--------------+------------------------------+
我目前用来执行此操作的视图如下:
DROP VIEW IF EXISTS view_logged_property;
CREATE VIEW view_logged_property as (
SELECT
p.event_id as ID,
(select log_value from property_log where log_key = "userId" and event_id = p.event_id) as UserID,
(select log_value from property_log where log_key = "licenseId" and event_id = p.event_id) as LicenseID,
(select log_value from property_log where log_key = "messageTypeId" and event_id = p.event_id) as MessageTypeID,
(select log_value from property_log where log_key = "message" and event_id = p.event_id) as Message
FROM
logging_event p
WHERE
p.event_id in (select event_id from property_log where log_key = "op" and log_value = "tracking")
);
编写此视图的最佳方法是什么,即使“property_log”表中的记录数增加,它也会表现良好?
答案 0 :(得分:1)
试试这个,
SELECT Event_ID,
MAX(CASE WHEN log_key = 'userID' THEN log_value ELSE NULL END) userID,
MAX(CASE WHEN log_key = 'licenseId ' THEN log_value ELSE NULL END) licenseId ,
MAX(CASE WHEN log_key = 'messageTypeId' THEN log_value ELSE NULL END) messageTypeId,
MAX(CASE WHEN log_key = 'message' THEN log_value ELSE NULL END) message,
MAX(CASE WHEN log_key = 'op' THEN log_value ELSE NULL END) op
FROM property_log
GROUP BY Event_ID
答案 1 :(得分:1)
在这种情况下,我会使用join
。
在评论left join
之后更改应解决问题。
DROP VIEW IF EXISTS view_logged_property;
CREATE VIEW view_logged_property as (
select
p1.event_id as ID,
p5.log_value as UserID,
p2.log_value as LicenseID,
p3.log_value as MessageTypeID,
p4.log_value as Message
from property_log p1
left join property_log p5 on p1.event_id = p5.event_id and p5.log_key = 'userId'
left join property_log p2 on p1.event_id = p2.event_id and p2.log_key = 'licenseId'
left join property_log p3 on p1.event_id = p3.event_id and p3.log_key = 'messageTypeId'
left join property_log p4 on p1.event_id = p4.event_id and p4.log_key = 'message'
where p1.log_key = 'op' and p1.log_value = 'tracking'
);
你能测试一下你的数据吗?
对event_id, log_key
对的索引可能是必需的,如下所示:
create index event_key_idx on property_log(event_id, log_key);