优化将多个记录合并为一个记录的mysql视图

时间:2012-11-28 14:34:30

标签: mysql sql optimization view

我正在尝试优化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”表中的记录数增加,它也会表现良好?

2 个答案:

答案 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);

SQL Fiddle example