0

4 GB のメモリを搭載した Windows7-Home を実行しているラップトップで、1,200 万行以上の DB にいくつかのクエリを作成します (研究予算のない大学教授)。次の列を utf8_bin としてスキーマに追加し、それらにインデックスを配置することを検討しています。これにより、クエリのパフォーマンスが向上しますか? 次のような単純なクエリには 100 秒以上かかります。

SELECT 'Aug' as Month, 
        SUM(volume) AS Volume 
FROM    moving_avgs
WHERE   data_date between 20120801 
        AND 20120831;
  • 追加してインデックスを作成する列:
    • 月、火、水、木、金
    • 1月、2月、3月、4月...12月
    • OpExp

私の現在のテーブル構造:

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;

これによりクエリ プランが表示され、それがテーブル スキャンであり、インデックスを使用していないことを確認できます。Explain ステートメントの出力を読み取ることができることは、クエリの最適化の非常に重要な部分です。

于 2013-01-18T06:17:29.893 に答える