0

在具有 4GB 内存的运行 Windows7-Home 的笔记本电脑上(没有研究预算的大学教授)在具有 12+ 百万行的数据库上编写一些查询。我正在考虑将以 utf8_bin 的形式添加到架构中并在其上放置索引。这会给我更好的查询性能吗?像下面这样的简单查询需要 100 多秒:

SELECT 'Aug' as Month, 
        SUM(volume) AS Volume 
FROM    moving_avgs
WHERE   data_date between 20120801 
        AND 20120831;
  • 我要添加和索引的列:
    • 周一,周二,周三,周四,周五
    • 一月、二月、三月、四月 ... 十二月
    • 运营商

我当前的表结构:

CREATE TABLE `moving_avgs` (
  `symbol` varchar(8) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
  `data_date` date NOT NULL DEFAULT '0000-00-00',
  `openprice` double(13,2) DEFAULT NULL,
  `highprice` double(13,2) DEFAULT NULL,
  `lowprice` double(13,2) DEFAULT NULL,
  `closeprice` double(13,2) DEFAULT NULL,
  `prior_close` double(13,2) DEFAULT NULL,
  `pror_e` double(8,4) DEFAULT NULL,
  `pror_l` double(8,4) DEFAULT NULL,
  `volume` bigint(20) DEFAULT NULL,
  `exchange` varchar(10) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
  `ma5_open` double(13,2) DEFAULT NULL,
  `ma10_open` double(13,2) DEFAULT NULL,
  `ma20_open` double(13,2) DEFAULT NULL,
  `ma30_open` double(13,2) DEFAULT NULL,
  `ma50_open` double(13,2) DEFAULT NULL,
  `ma90_open` double(13,2) DEFAULT NULL,
  `ma200_open` double(13,2) DEFAULT NULL,
  `ma5_high` double(13,2) DEFAULT NULL,
  `ma10_high` double(13,2) DEFAULT NULL,
  `ma20_high` double(13,2) DEFAULT NULL,
  `ma30_high` double(13,2) DEFAULT NULL,
  `ma50_high` double(13,2) DEFAULT NULL,
  `ma90_high` double(13,2) DEFAULT NULL,
  `ma200_high` double(13,2) DEFAULT NULL,
  `ma5_low` double(13,2) DEFAULT NULL,
  `ma10_low` double(13,2) DEFAULT NULL,
  `ma20_low` double(13,2) DEFAULT NULL,
  `ma30_low` double(13,2) DEFAULT NULL,
  `ma50_low` double(13,2) DEFAULT NULL,
  `ma90_low` double(13,2) DEFAULT NULL,
  `ma200_low` double(13,2) DEFAULT NULL,
  `ma5_close` double(13,2) DEFAULT NULL,
  `ma10_close` double(13,2) DEFAULT NULL,
  `ma20_close` double(13,2) DEFAULT NULL,
  `ma30_close` double(13,2) DEFAULT NULL,
  `ma50_close` double(13,2) DEFAULT NULL,
  `ma90_close` double(13,2) DEFAULT NULL,
  `ma200_close` double(13,2) DEFAULT NULL,
  `ma5_volume` int(15) DEFAULT NULL,
  `ma10_volume` int(15) DEFAULT NULL,
  `ma20_volume` int(15) DEFAULT NULL,
  `ma30_volume` int(15) DEFAULT NULL,
  `ma50_volume` int(15) DEFAULT NULL,
  `ma90_volume` int(15) DEFAULT NULL,
  `ma200_volume` int(15) DEFAULT NULL,
  `volt5_l` double(8,4) DEFAULT NULL,
  `volt10_l` double(8,4) DEFAULT NULL,
  `volt20_l` double(8,4) DEFAULT NULL,
  `volt30_l` double(8,4) DEFAULT NULL,
  `volt50_l` double(8,4) DEFAULT NULL,
  `volt90_l` double(8,4) DEFAULT NULL,
  `volt200_l` double(8,4) DEFAULT NULL,
  `volt5_e` double(8,4) DEFAULT NULL,
  `volt10_e` double(8,4) DEFAULT NULL,
  `volt20_e` double(8,4) DEFAULT NULL,
  `volt30_e` double(8,4) DEFAULT NULL,
  `volt50_e` double(8,4) DEFAULT NULL,
  `volt90_e` double(8,4) DEFAULT NULL,
  `volt200_e` double(8,4) DEFAULT NULL,
  PRIMARY KEY (`data_date`,`symbol`,`exchange`),
  KEY `symbol` (`symbol`),
  KEY `data_date` (`data_date`),
  KEY `exchange` (`exchange`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

我可以用 my.ini 做些什么吗?

[mysqld]
port        = 3306
socket      = /tmp/mysql.sock
skip-external-locking
key_buffer_size = 128M
max_allowed_packet = 20M
table_open_cache = 256
max_heap_table_size = 128M
tmp_table_size = 512M
sort_buffer_size = 512M
read_buffer_size = 32M
read_rnd_buffer_size = 16M
myisam_sort_buffer_size = 128M
thread_cache_size = 8
query_cache_size= 64M
basedir=c:/wamp/bin/mysql/mysql5.5.24
log-error=c:/wamp/logs/mysql.log
datadir=c:/wamp/bin/mysql/mysql5.5.24/data
# Try number of CPU's*2 for thread_concurrency
thread_concurrency = 8

以下是 EXPLAIN 的结果:

explain select 'Aug' as Month, sum(volume) as Volume from moving_avgs
where data_date between '2012-08-01' and '2012-08-31';

id select_type table       type  possible_keys     key     key_len ref  rows   extra
-- ----------- ----------- ----- ----------------- ------- ------- ---- ------ -----------
1  SIMPLE      moving_avgs range PRIMARY,data_date PRIMARY 3       NULL 110906 Using where

非常感谢!

4

1 回答 1

0

从您的表定义来看,您的表上没有任何二级索引。由于您的查询使用日期范围来确定要返回的记录并且没有索引,因此查询将执行表扫描。

添加其他索引和列可能会在插入和更新期间减慢速度,因此不要添加它们。

只需在 data_date 列上添加一个索引,这样查询就可以使用这个索引来加快读取速度。我建议您是否可以在您的问题中发布以下语句的结果:

EXPLAIN SELECT 'Aug' as Month, 
        SUM(volume) AS Volume 
FROM    moving_avgs
WHERE   data_date between 20120801 
    AND 20120831;

这将向我显示查询计划,我将能够确认它是表扫描而不是使用索引。能够读取解释语句的输出是查询优化的一个非常重要的部分。

于 2013-01-18T06:17:29.893 回答