簡體   English   中英

非常慢的簡單mysql查詢

[英]Very slow simple mysql query

我有一個非常慢的mysql查詢,如下所示:

SELECT function,  CONVERT_TZ(`time`, '+01:00','+01:00') 
FROM `function_logger` 
WHERE unit_id=3067785 
  and part_id=3 and channel=0  
  and `time` > NOW()-INTERVAL 1 DAY 
order by time;

用於以下表格結構

CREATE TABLE IF NOT EXISTS `function_logger` (
  `id` int(11) NOT NULL,
  `unit_id` int(11) NOT NULL,
  `part_id` tinyint(4) NOT NULL DEFAULT '0',
  `channel` tinyint(4) NOT NULL DEFAULT '0',
  `function` tinyint(11) NOT NULL,
  `time` datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

ALTER TABLE `function_logger`
  ADD PRIMARY KEY (`id`),
  ADD KEY `unit_id` (`unit_id`);

該表包含約8000萬條記錄,但運行大約需要一分鍾。 一旦緩存就可以了。

unit_id包含大約3000個不同的隨機數,part_id最多10個,通道最多3個。

反正有加速的嗎?

分區會有所幫助嗎?

假設unit_id分布均勻,然后在80m條記錄中選擇特定的一項(從3000條中選擇),則您有超過25k條記錄需要檢查。

由於您沒有進一步的索引幫助,MySQL當前必須檢索並檢查這25k條記錄中的每條記錄,以確定它們是否與其余過濾條件匹配。

添加復合索引(即在多個列上定義的復合索引)將在這里為您提供幫助-MySQL可以進一步減少它需要檢查的記錄。 但是,由於基數很低, part_idchannel可能無濟於事。 目前尚不清楚,從可能存在什么樣的基數的time ,但是這可能是一個很好的起點:

CREATE INDEX unit_time ON function_logger (unit_id, time)

您也可以添加其他過濾器列(盡管要注意time應該倒數,因為您正在搜索一個范圍)—但是,索引中的列越多,寫入表的速度就越慢(並且越大索引文件和內存占用量)。

最快的讀取性能將通過覆蓋指數獲得:

CREATE INDEX covering ON function_logger (
  unit_id, part_id, channel, time, function
)

嘗試/測試不同的索引時,請執行解釋並比較結果。 USE INDEX將幫助您測試不同的索引,並在select語句中添加該提示(請不要使用qc)。

set profiling = on;

select * from function_logger;
show profiles;
show profile for query N;

暫無
暫無

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

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