2012-08-11 86 views
0

我有一個MySQL查詢有時需要1秒鐘才能執行。查詢如下:如何使此MySQL查詢更快?

SELECT `id`,`totaldistance` FROM `alltrackers` WHERE `deviceid`='FT_99000083426364' AND (`gpsdatetime` BETWEEN 1341100800 AND 1342483200) ORDER BY `id` DESC LIMIT 1 

該查詢運行在一個循環中,以檢索月份某些日子的行等。這將導致頁面接管25秒有時加載...

表結構如下:

CREATE TABLE IF NOT EXISTS `alltrackers` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `deviceid` varchar(50) NOT NULL, 
    `lat` double NOT NULL, 
    `long` double NOT NULL, 
    `gpsdatetime` int(11) NOT NULL, 
    `version` int(11) DEFAULT NULL, 
    `totaldistance` int(11) NOT NULL DEFAULT '0', 
    `distanceprocessed` tinyint(1) NOT NULL DEFAULT '0', 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `id_deviceid` (`id`,`deviceid`), 
    UNIQUE KEY `deviceid_id` (`deviceid`,`id`), 
    KEY `deviceid` (`deviceid`), 
    KEY `deviceid_gpsdatetime` (`deviceid`,`gpsdatetime`), 
    KEY `gpsdatetime_deviceid` (`gpsdatetime`,`deviceid`), 
    KEY `gpsdatetime` (`gpsdatetime`), 
    KEY `id_deviceid_gpsdatetime` (`id`,`deviceid`,`gpsdatetime`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=677242 ; 

我已經加入各項指標的組合(請告訴我哪刪除)在爲了試圖讓MySQL使用索引進行查詢,但無濟於事。

這裏是EXPLAIN輸出:

id select_type table type possible_keys key key_len ref rows Extra 
1 SIMPLE alltrackers index deviceid_id,deviceid,deviceid_gpsdatetime,gpsdatet... PRIMARY 4 NULL 677238 Using where 

我使用ORDER BY ASC/DESC LIMIT 1的原因是因爲我需要查詢的第一行和最後一行。運行沒有LIMIT 1的查詢並使用PHP檢索第一行和最後一行會更快嗎?

非常感謝您的幫助!

+1

重複索引不起作用。您可以要求MySQL [使用特定索引](http://dev.mysql.com/doc/refman/5.5/en/index-hints.html)。你可以嘗試一個想法:爲時間段創建一個(臨時?)表,加入那個表而不是硬編碼範圍,'SELECT device_id,MAX(id)WHERE

回答

0

我不能說你的確切情況,但我發現查詢所有行並忽略除第一個以外的所有行比限制語句(儘管這是使用SQL Server)更快。它很容易做 - 刪除您的限制1條款,並試一試。然後,您可以使用PHP讀取第一個和最後一個,從而減少MySQL實例的負載(即運行單個查詢而不是2個)。順便說一句,爲什麼你有2個唯一的鍵與他們相同的列 - id_deviceid和deviceid_id?刪除所有索引,然後再次將它們添加回來,對於快速數據庫,您確實需要儘可能少的索引。

+0

謝謝。我刪除了限制,並使用mysql_seek_row命令讀取第一個和最後一個結果。 LIMIT導致查詢運行緩慢並忽略索引... – SeBsZ 2012-08-13 11:46:51

0

夫婦的事情,我能想到的把我的頭頂部:

1)我沒有任何延伸一個MySQL/DBA大師,但指數似乎好像有點矯枉過正。通常我會確保查詢或加入的列被索引;所以你想要一個deviceid和gpsdatetime。每個查詢1秒不是可怕的,所以你在這裏的回報可能是有限的。

2.)嘗試消除循環。如果你要回到數據庫25次;你只需要打開/關閉連接等。一次訪問數據庫可能會更快,然後使用PHP處理結果以獲取所需的最終數據。