2013-05-15 51 views
0

我們有一個在MySQL數據庫中相當靜態的數據集,但是讀取時間很糟糕(甚至在查詢列的索引時也是如此)。理論上說,由於行是隨機存儲的(或者有時按照插入順序存儲),所以磁盤頭必須掃描以找到不同的行,即使它知道索引所在的位置,而不是僅依次讀取它們。在MySQL中更改磁盤上的數據組織

是否有可能改變訂單數據存儲在磁盤上,以便它可以順序讀取?不幸的是,我們現在不能添加更多的RAM來緩存所有的查詢。如果可以更改訂單,我們可以在訂單內定義訂單嗎?如在列中排序,如果第一列相同,則按另一列排序。

這可能與索引有關嗎?

其他詳細信息:非關係型單表數據庫,包含1600萬行,1 GB數據總量,512 MB內存,Ubuntu 12.04上帶有標準硬盤驅動器的MariaDB 5.5.30。另外這是一個使用OpenVZ的,2虛擬機專用核心E5-2620 CPU 2Ghz的

創建語法:

CREATE TABLE `Events` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `provider` varchar(10) DEFAULT NULL, 
    `location` varchar(5) DEFAULT NULL, 
    `start_time` datetime DEFAULT NULL, 
    `end_time` datetime DEFAULT NULL, 
    `cost` int(11) DEFAULT NULL, 
    PRIMARY KEY (`id`), 
    KEY `provider` (`provider`), 
    KEY `location` (`location`), 
    KEY `start_time` (`start_time`), 
    KEY `end_time` (`end_time`), 
    KEY `cost` (`cost`) 
) ENGINE=InnoDB AUTO_INCREMENT=02 DEFAULT CHARSET=utf8; 

這需要很長的時間Select語句:

SELECT * 
FROM `Events` 
WHERE `Events`.start_time >= '2013-05-03 23:00:00' AND `Events`.start_time <= '2013-06-04 22:00:00' AND `FlightRoutes`.location = 'Chicago' 

解釋選擇:

1 SIMPLE Events ref location,start_time location 18 const 3684 Using index condition; Using where 
+0

是的,它可能是隨機磁盤I/O是你的問題;是的,有些事情可以用來重構磁盤上的數據。但是,在這樣做之前,讓我們檢查一下您的查詢是否使用了合適的索引;請顯示錶模式,查詢及其執行計劃:'SHOW CREATE TABLE foo','SELECT ...'和'EXPLAIN SELECT ...'。 – eggyal

+0

非常感謝您的回答。上面添加了語法和更多信息。 – AC360

+0

您的數據不是「隨機」存儲的,MySQL根據您的主鍵(「聚簇索引」)對數據進行排序。由於存儲數據的文件碎片化,它可能會隨機結束。從MySQL的角度來看,數據是通過'id'排序的 –

回答

0

MySQL只能選擇一個 (這是有道理的,因爲使用索引限制了結果,所以它不能確定這樣的限制如何影響其他索引)。因此,它跟蹤每個指數的基數並選擇可能最具選擇性的基數(即具有最高基數):在這種情況下,它選擇了location指數,但通常會留下3,684條必須是獲取並過濾Using where以找到與期望範圍start_time匹配的那些。

你應該嘗試創建一個composite index(location, start_time)

ALTER TABLE Events ADD INDEX (location, start_time) 
+0

非常感謝!它的工作速度更快!現在我想知道是否有任何其他查詢優化,我們可以做?我應該研究什麼東西來最大限度地提高磁盤I/O?再次感謝! – AC360

+0

@ AC360:對所做的一切都有權衡,所以要小心才能達到令人滿意的性能;記住Knuth的格言「*過早優化是所有邪惡的根源*」。但是,如果性能仍然不理想,您應該首先*查找您的查詢,以準確發現所花時間;如果磁盤I/O確實爲您提供了重大問題,您可以考慮[分區](http://dev.mysql.com/doc/en/partitioning.html)數據 - 但不要在調整各種服務器之前引擎專用設置;但在許多情況下,硬件升級可能是首選。 – eggyal

+0

@eggyval:只是一個側面說明:「*有道理*」並不完全正確。有幾個DBMS可以有效地在查詢中爲一個表使用多個索引。 –