[英]MySQL query takes a long time to run
我的表定義如下:
CREATE TABLE `tracking_info` (
`tid` int(25) NOT NULL AUTO_INCREMENT,
`tracking_customer_id` int(11) NOT NULL DEFAULT '0',
`tracking_content` text NOT NULL,
`tracking_type` int(11) NOT NULL DEFAULT '0',
`time_recorded` int(25) NOT NULL DEFAULT '0',
PRIMARY KEY (`tid`),
KEY `time_recorded` (`time_recorded`),
KEY `tracking_idx` (`tracking_customer_id`,`tracking_type`,
`time_recorded`,`tid`)
) ENGINE=MyISAM
該表包含大約 1.5 億條記錄。 這是查詢:
SELECT tracking_content, tracking_type, time_recorded
FROM tracking_info
WHERE FROM_UNIXTIME(time_recorded) > DATE_SUB( NOW( ) ,
INTERVAL 90 DAY )
AND tracking_customer_id = 111111
ORDER BY time_recorded DESC
LIMIT 0,10
即使沒有 ORDER BY,運行查詢也需要大約一分鍾。 有什么想法嗎? 提前致謝!
首先,重構查詢,使其成為sargable 。
SELECT tracking_content, tracking_type, time_recorded
FROM tracking_info
WHERE time_recorded > UNIX_TIMESTAMP(DATE_SUB( NOW( ) , INTERVAL 90 DAY )
AND tracking_customer_id = 111111
ORDER BY time_recorded DESC
LIMIT 0,10;
然后添加這個多列索引:
ALTER TABLE tracking_info
ADD INDEX cust_time (tracking_customer_id, time_recorded DESC);
為什么會有幫助?
它將列中的原始數據與常量進行比較,而不是使用FROM_UNIXTIME()
函數來轉換表中該列中的所有數據。 這使得查詢sargable 。
查詢計划器可以隨機訪問我建議的第一個符合條件的行的索引,然后從索引中順序讀取十行並從表中查找它需要的內容,然后停止。
您可以改寫查詢以隔離time_recorded
,如下所示:
SELECT tracking_content, tracking_type, time_recorded
FROM tracking_info
WHERE time_recorded > UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 90 DAY))
AND tracking_customer_id = 111111
ORDER BY time_recorded DESC
LIMIT 0,10
然后,以下索引可能會使查詢更快:
create index ix1 on tracking_info (tracking_customer_id, time_recorded);
有 3 件事要做:
更改為 InnoDB。
添加INDEX(tracking_customer_id, time_recorded)
改寫為time_recorded > NOW() - INTERVAL 90 DAY)
非關鍵注釋:
int(25)
-- "25" 沒有意義。 無論如何,您都會得到一個 4 字節的有符號數字。DATETIME
和TIMESTAMP
; 考慮使用其中之一而不是表示自某個時間以來的秒數的INT
。 (更改會很麻煩,所以不要打擾。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.