簡體   English   中英

MySQL JSON_EXTRACT性能

[英]MySQL JSON_EXTRACT performance

我們有一個日志表,該表隨着新事件的發生而增長。 目前,我們存儲了約120.000行日志事件。

事件表如下所示:

'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字段來過濾某個特定應用程序的信息,例如:

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'

通過此查詢,可以得出最近30天內創建任務最多的前10個項目。 工作正常,但是隨着我們表的增長,這個查詢變得越來越慢。 對於120.000行,此查詢需要30秒鍾以上。

您知道提高速度的任何方法嗎? 表中ID最高的最新信息比舊條目更重要。 我經常只查找最近X天發生的條目。 在第一個條目距where子句的日期早於X天之后,停止查詢是有用的,因為所有其他條目都更舊了。

如果TIME_STAMP已建立索引,則DATE函數將不允許使用該索引,因為它是不確定的。

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

可以重寫為。

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

您知道提高速度的任何方法嗎?

我能看到的加快查詢速度的唯一方法是像這樣對多列索引TIMESTAMP和ORIGIN進行索引,這樣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;    

我已經減少了行數的內部選擇可以將查詢時間從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;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM