2017-09-26 731 views
-1

我們有一個日誌表,它隨着新事件的發生而不斷增長。目前我們有大約120.000行的日誌事件存儲。MySQL JSON_EXTRACT性能

事件表看起來是這樣的:

'CREATE TABLE `EVENTS` (
`ID` int(11) NOT NULL AUTO_INCREMENT, 
`EVENT` varchar(255) NOT NULL, 
`ORIGIN` varchar(255) NOT NULL, 
`TIME_STAMP` TIMESTAMP NOT NULL, 
`ADDITIONAL_REMARKS` json DEFAULT NULL, 
PRIMARY KEY (`ID`) 
) ENGINE=InnoDB AUTO_INCREMENT=137007 DEFAULT CHARSET=utf8' 

Additional_Remarks是一個JSON字段,因爲不同的應用程序登錄到這個表,可以到發生事件添加更多信息。我不想在這裏放置任何數據結構,因爲這些信息可能會有所不同。例如,一個項目管理應用程序可登錄:

ID, "new task created", "app", NOW(), {"project": {"id": 1}, "creator": {"id": 1}} 

雖然其他應用程序沒有他們想要的Additional_Remarks字段來存儲項目或創造者,但也許貓和主人。

查詢可以使用Additional_Remarks字段爲一個特定的應用程序過濾信息,如:

SELECT 
DISTINCT(ADDITIONAL_REMARKS->"$.project.id") as 'project', 
COUNT(CASE WHEN EVENT = 'new task created' THEN 1 END) AS 'new_task' 
FROM EVENTS 
WHERE DATE(TIMESTAMP) >= DATE(NOW()) - INTERVAL 30 DAY 
AND ORIGIN = "app" 
GROUP BY project 
ORDER BY new_task DESC 
LIMIT 10; 

輸出EXPLAIN查詢:

'1', 'SIMPLE', 'EVENTS', NULL, 'ALL', NULL, NULL, NULL, NULL, '136459', '100.00', 'Using where; Using temporary; Using filesort' 

與此查詢我得到的前10個項目,最創建過去30天的任務。工作正常,但隨着我們的表增長,這個查詢變得越來越慢。有了120.000行這個查詢需要超過30秒。

你知道任何提高速度的方法嗎?表格中具有最高ID的最新信息比較老的條目更重要。我經常只看看最近X天發生的事情。在第一個條目比where子句中的X天更早之後停止查詢會很有用,因爲所有其他條目都更老。

+0

有關查詢性能的問題應該包括'SHOW CREATE TABLE EVENTS',所以我們可以看到,如果有或索引或沒有。其次,應該包含'EXPLAIN [query]'的輸出。 –

+0

感謝您的建議。我加了兩個問題。 – user1482309

+0

您忘記將列ORIGIN放在create table語句中了嗎? –

回答

0

內部選擇,我已經減少行數可以減少查詢時間從30秒到0.05秒。

它看起來像:

SELECT 
ADDITIONAL_REMARKS->"$.project.id" AS 'project', 
COUNT(CASE WHEN EVENT = 'new task created' THEN 1 END) AS 'new_task' 
FROM ( 

SELECT * 
    FROM EVENTS WHERE 
    EVENT = 'new task created' 
    AND TIME_STAMP >= UNIX_TIMESTAMP(DATE(NOW()) - INTERVAL 30 DAY) 
    AND ORIGIN = "app") AS events_within_30_days 

GROUP BY project 
ORDER BY new_task DESC 
LIMIT 10; 
1

如果對TIME_STAMP進行索引,則DATE函數將不允許使用索引,因爲它是非確定性的。

WHERE DATE(TIMESTAMP) >= DATE(NOW()) - INTERVAL 30 DAY 

可以改寫爲。

WHERE TIMESTAMP >= UNIX_TIMESTAMP(DATE(NOW()) - INTERVAL 30 DAY) 

你知道什麼辦法來提高速度?

我可以看到,以加快查詢的唯一方法是多列索引TIMESTAMP和起源,像這樣ALTER TABLE EVENTS ADD KEY timestamp_origin (TIME_STAMP, ORIGIN);和礦山查詢調整上述

編輯

而一個傳遞表可以改善查詢速度,因爲它會使用新的索引。

SELECT 
    ADDITIONAL_REMARKS->"$.project.id" AS 'project', 
    COUNT(CASE WHEN EVENT = 'new task created' THEN 1 END) AS 'new_task' 
FROM ( 

    SELECT 
    * 
    FROM EVENTS 
    WHERE 
    TIME_STAMP >= UNIX_TIMESTAMP(DATE(NOW()) - INTERVAL 30 DAY) 
    AND 
    ORIGIN = "app" 
) 
AS events_within_30_days 

GROUP BY project 
ORDER BY new_task DESC 
LIMIT 10;  
+0

首先:感謝您的幫助!現在我在TIMESTAMP和ORIGIN上有一個BTREE多列索引。但是查詢仍然需要同一時間。 – user1482309

+0

@ user1482309沒問題,可以是新索引沒有被使用。我已經更新了我的答案,使用交付的表應該使用新的索引交付的表可能會改善查詢執行...但您的查詢很難優化,我認爲,因爲您關閉了動態列,並按順序排列。 –

+0

我試着添加內部選擇,添加差異索引策略,並且還將id> xxx到的位置替換爲。沒有不同。現在我想到一個沒有JSON字段的完整新策略,比如ADDITIONAL_REMARKS。 – user1482309