2013-03-02 112 views
0

我們有以下MySQL表有大約150萬行:添加索引,優化MySQL查詢

CREATE TABLE `data` (
    `datetime` datetime NOT NULL, 
    `value1` decimal(12,6) NOT NULL, 
    `value2` decimal(12,6) NOT NULL, 
    `value3` decimal(12,6) NOT NULL, 
    `value4` decimal(12,6) NOT NULL, 
    `value5` decimal(12,6) NOT NULL, 
    `symbol_id` int(11) NOT NULL, 
    PRIMARY KEY (`symbol_id`,`datetime`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 

的1.5億行平分9500個符號之間,通過symbol_id指定。

我想這個表上運行以下查詢:

SELECT datetime FROM data WHERE symbol_id = 1234 AND datetime <= "2013-03-01 15:00:00" ORDER BY datetime DESC LIMIT 1 

運行的查詢返回的講解:

  id: 1 
    select_type: SIMPLE 
     table: data 
     type: range 
possible_keys: PRIMARY 
      key: PRIMARY 
     key_len: 12 
      ref: NULL 
     rows: 23856 
     Extra: Using where; Using index 

查詢平均需要運行約300毫秒。我可以添加哪些索引以加快速度?

謝謝!

+3

300毫秒,通過3.5億行是非常好的。也許你需要考慮升級你的硬件來滿足你的性能規格。 – 2013-03-02 22:31:06

+0

也在'value'字段使用'INDEX'? – hjpotter92 2013-03-02 22:32:01

+0

它實際上是150百萬行,但事情是查詢對某些符號運行速度非常快,但不是全部。 – user1094786 2013-03-02 22:39:49

回答

2

正如Gordon暗示的那樣,沒有索引可以提高查詢的性能。

這並不是說你沒有辦法讓它更快 - 調整你的DBMS和操作系統I/O - 你還沒有提供任何關於它當前如何配置的信息,它的運行方式以及使用模式像。如果你還沒有開始這個過程,那麼對你的安裝運行mysqltuner.pl將是一個好的開始 - 但它並不總是完全正確的。使用不同的引擎可以提高此查詢的性能 - 但這取決於系統上正在進行的其他操作。

通過在多個磁盤上分割索引和/或使用SSD存儲索引,您將獲得巨大收益。更多的內存總是有幫助。

get a good book關於MySQL調優,花時間讀它。

0

該查詢的性能可以通過索引得到改進,但首先必須確定列的基數。

SELECT COUNT(DISTINCT `datetime`) FROM `data`; 
SELECT COUNT(DISTINCT `symbol_id`) FROM `data`; 

無論返回唯一值的最高數具有更高的基數,並具有最佳的綜合指數,列必須是在降序基數順序。

您目前有一個列按以下順序的複合主鍵。

PRIMARY KEY (`symbol_id`,`datetime`) 

如果symbol_id具有比datetime更高的基數,那麼查詢不能進一步優化。另一方面,如果日期時間具有較高的基數,那麼您應該添加一個帶有日期時間後跟symbol_id的索引。

INDEX idx_datetime_symbol (`datetime`,`symbol_id`)