2012-11-28 149 views
0

我想優化MySql中的視圖。該視圖從表中取0-5條記錄並將它們轉換爲1條記錄。該視圖起作用,但隨着property_log表中記錄數的增加而減慢。優化將多個記錄合併到一個記錄中的mysql視圖

例如,數據看起來像這樣:

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」表中的記錄數增加時,它的表現也會很好嗎?

回答

1

我想在這種情況下使用join秒。

更改後發表評論left join s應解決問題。

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

+0

嘿!我試過這個,它並沒有給我任何數據......但那是因爲我沒有意識到並非所有的記錄都會一直存在(例如,有時只有4條記錄)。我已經添加了對這個問題的澄清! –

+0

@BradParks因此而不是'join'使用['left join'](http://en.wikipedia.org/wiki/Join_%28SQL%29#Left_outer_join),回答正確。 –

+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