如何使用多个ORDER BY子句索引表?

时间:2013-01-25 10:50:23

标签: mysql indexing sql-order-by

我有一张表IntradayPrices1Minute,其中我存储了1分钟的时间范围开放,高,低和收盘价格:

CREATE TABLE `IntradayPrices1Minute` (
  `ticker` varchar(10) NOT NULL DEFAULT '',
  `datetime` datetime NOT NULL,
  `volume` mediumint(11) unsigned NOT NULL,
  `open` decimal(8,4) unsigned NOT NULL,
  `high` decimal(8,4) unsigned NOT NULL,
  `low` decimal(8,4) unsigned NOT NULL,
  `close` decimal(8,4) unsigned NOT NULL,
  PRIMARY KEY (`ticker`,`datetime`),
  UNIQUE KEY `indxTickerDatetime` (`ticker`,`datetime`)
)

我已经构建了一个查询,我可以计算这些股票的每日开盘价,最高价,最低价和收盘价。这是查询:

select 
    `IntradayPrices1Minute`.`ticker` AS `ticker`,
    cast(`IntradayPrices1Minute`.`datetime` as date) AS `Date`,
    substring_index(group_concat(cast(`IntradayPrices1Minute`.`open` as char charset utf8) order by `IntradayPrices1Minute`.`datetime` ASC separator ','),',',1) AS `Daily Open`,
    max(greatest(`IntradayPrices1Minute`.`open`,`IntradayPrices1Minute`.`high`,`IntradayPrices1Minute`.`low`,`IntradayPrices1Minute`.`close`)) AS `Daily High`,
    min(least(`IntradayPrices1Minute`.`open`,`IntradayPrices1Minute`.`high`,`IntradayPrices1Minute`.`low`,`IntradayPrices1Minute`.`close`)) AS `Daily Low`,
    substring_index(group_concat(cast(`IntradayPrices1Minute`.`close` as char charset utf8) 

order by 
   `IntradayPrices1Minute`.`datetime` DESC separator ','),',',1) AS `Daily Close` 
from    
   `IntradayPrices1Minute` 

group by 
   `IntradayPrices1Minute`.`ticker`,
   cast(`IntradayPrices1Minute`.`datetime` as date)

这是我在仅有4-5天的数据时获得的结果的一部分(截至今天我有更多的数据天):

ticker  Date        Open    High    Low     Close
----    ----------  ------  ------  ------  ------ 
AAAE    2012-11-26  0.0100  0.0100  0.0100  0.0100
AAAE    2012-11-27  0.0130  0.0140  0.0083  0.0140
AAAE    2012-11-28  0.0140  0.0175  0.0140  0.0165
AAAE    2012-11-29  0.0175  0.0175  0.0137  0.0137
AAMRQ   2012-11-26  0.4411  0.5300  0.4411  0.5290
AAMRQ   2012-11-27  0.5100  0.5110  0.4610  0.4950
AAMRQ   2012-11-28  0.4820  0.4900  0.4300  0.4640
AAMRQ   2012-11-29  0.4505  0.4590  0.4411  0.4590
AAMRQ   2012-11-30  0.4500  0.4570  0.4455  0.4568

截至今天,IntradayPrices1Minute表已经 9625952 记录并且增长了大约。每天350000条记录

使用LIMIT 1000执行上一个SELECT已经需要超过8秒,所以我想出了一些索引是需要的,但是我对索引的知识以及如何决定它们是非常有限的。

我认为有些信息对于那些对此有更多专业知识的人有用:

show indexes from IntradayPrices1Minute

返回:

IntradayPrices1Minute   0   PRIMARY 1   ticker  A   32368               BTREE       
IntradayPrices1Minute   0   PRIMARY 2   datetime    A   9872508             BTREE       
IntradayPrices1Minute   0   indxTickerDatetime  1   ticker  A   21793               BTREE       
IntradayPrices1Minute   0   indxTickerDatetime  2   datetime    A   9872508             BTREE       

并显示show profiling命令:

Status                 Duration
------                 --------
starting               0.000055
checking permission    0.000003
Opening tables         0.000018
System lock            0.000005
init                   0.000022
optimizing             0.000004
statistics             0.000011
preparing              0.000006
executing              0.000027
Sorting result         8.533655
Sending data           0.233446
end                    0.000010
removing tmp table     0.000006
end                    0.000007
removing tmp table     0.000002
end                    0.000005
query end              0.000003
closing tables         0.000004
freeing items          0.000041
logging slow query     0.000002
cleaning up            0.000003

不幸的是,由于我的知识有限,这些信息对我没什么用处。我怀疑所有那些ORDER BY可能都是如此密集,因为节目分析表明8,53秒被用于“排序结果”但我不知道如何处理这个以使查询有效。

非常感谢您提出任何建议,特别是如果它能帮助我更好地为未来的查询编制索引,我可能还需要对其进行故障排除。

欢呼声, 博加

1 个答案:

答案 0 :(得分:2)

尝试更改

GROUP BY ticker, date(datetime)

进入

GROUP BY ticker, datetime

第一个不使用索引,因此需要(非常慢)文件排序。第二个是使用索引,速度更快。

您可以使用以下方法找到此类问题:

EXPLAIN SELECT * FROM table