Mysql
在分區表中搜尋很慢
我在 Ubuntu 伺服器 16.04 上執行 MySQL 5.7.15。
在我按範圍對錶進行分區後,某些值的選擇查詢很慢。如果舊分區中缺少密鑰,我已經檢查過查詢很慢。
CREATE TABLE `table` ( `id` bigint(20) unsigned NOT NULL, `clock` int(11) NOT NULL DEFAULT '0', `value` bigint(20) unsigned NOT NULL DEFAULT '0', KEY `table_1` (`id`,`clock`), KEY `clock` (`clock`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 /*!50100 PARTITION BY RANGE (clock) (PARTITION p2016_10_16 VALUES LESS THAN (1476655200) ENGINE = InnoDB, PARTITION p2016_10_17 VALUES LESS THAN (1476741600) ENGINE = InnoDB, PARTITION p2016_10_18 VALUES LESS THAN (1476828000) ENGINE = InnoDB, PARTITION p2016_10_19 VALUES LESS THAN (1476914400) ENGINE = InnoDB, PARTITION p2016_10_20 VALUES LESS THAN (1477000800) ENGINE = InnoDB, PARTITION p2016_10_21 VALUES LESS THAN (1477087200) ENGINE = InnoDB) */|
執行查詢:
select * from table where id='25885' and clock>1476044179 order by clock desc limit 3;
…花費超過 1 秒,可能是因為最後一個分區中只有條目(15 個元組)。
如果我改為執行:
select * from table where id='24946' and clock>1476044179 order by clock desc limit 3;
…查詢更快(快得多)可能是因為所有分區中都有條目(8k 元組)。
我錯過了什麼?
您似乎對使用
id
查詢優化器的密鑰分配有疑問。由於
id
沒有考慮到分區方案,我只看到 MySQL 必須查找多達id
6 次。根據id
寫入每個值的時間和頻率,查詢可能使用了錯誤的索引。您可以做兩件事來查看
id
密鑰分配是否存在問題建議 #1:
EXPLAIN
在每個查詢上執行explain select * from table where id='25885' and clock>1476044179 order by clock desc limit 3; explain select * from table where id='24946' and clock>1476044179 order by clock desc limit 3;
輸出將告訴您選擇了哪個索引來掃描行。如果
clock
正在使用索引,則clock
正在索引中掃描 ,但id
正在從表中掃描 。建議#2:改變
ORDER BY
如果
order by clock desc
讓查詢優化器選擇clock
索引,試試這個:order by id,clock desc
這樣,掃描將從
table_1
索引開始,從最後一次id
插入 an 開始。試一試 !!!
您的分區是以時鐘為基礎的。您提供的時鐘值位於第一個分區..因此它將從第一個分區搜尋到最後一個分區…即它將遍歷所有分區以獲取值..
如果 Id 是數據庫的自動增量主鍵.. 那麼第二個查詢中的 id 小於第一個查詢中的那個.. 它更早地找到它.. 隨著 id 的分區越多,所花費的時間越多是。
如果您對 id 進行分區並且您不必總是遍歷每個索引,您的查詢將會快得多。
分區對於更快的查詢執行沒有作用,因為您已經指定了使其通過所有分區的約束。如果您給出的時鐘值位於第 4 或第 5 分區中.. 它會搜尋第 4 或第 5分區向前分區..從而從搜尋中保存前4個分區,查詢會更快
希望這能回答你的問題。