一尘不染

MySQL提高SELECT速度

sql

我目前正在尝试提高MySQL表的SELECTS的速度,并且希望就改进它的方法提出任何建议。

该表中有3亿条记录,并且该表具有结构标签,日期和值。主键是标签和日期的组合键。该表包含约600个唯一标签的信息,其中大多数平均包含约40万行,但范围可能从2000行到超过1100万行。

针对表运行的查询为:

  SELECT date,
         value 
    FROM table 
   WHERE tag = "a" 
     AND date BETWEEN 'x' and 'y' 
ORDER BY date

....并且几乎没有(如果有的话)插入。

我曾尝试通过标签将数据划分为多个分区,但是速度似乎没有增加。


阅读 233

收藏
2021-03-17

共1个答案

一尘不染

花点时间在这里阅读我的答案:(与您的书卷相似)

在0.02秒内扫描5亿行,1500万行。

MySQL和NoSQL:帮助我选择合适的一个

然后将表引擎修改为innodb,如下所示:

create table tag_date_value
(
tag_id smallint unsigned not null, -- i prefer ints to chars
tag_date datetime not null, -- can we make this date vs datetime ?
value int unsigned not null default 0, -- or whatever datatype you require
primary key (tag_id, tag_date) -- clustered composite PK
)
engine=innodb;

您可以考虑将以下内容作为主键:

primary key (tag_id, tag_date, value) -- added value save some I/O

但是仅当值不是某些大型varchar类型时!

像以前一样查询:

select
 tag_date, 
 value
from
 tag_date_value
where
 tag_id = 1 and
 tag_date between 'x' and 'y'
order by
 tag_date;

希望这可以帮助 :)

编辑

哦,忘记了-不要使用altertable将引擎类型从mysiam更改为innodb,而是将数据转储到csv文件中,然后重新导入到新创建的空innodb表中。

请注意,我在导出过程中正在对数据进行排序-聚集索引是关键!

出口

select * into outfile 'tag_dat_value_001.dat' 
fields terminated by '|' optionally enclosed by '"'
lines terminated by '\r\n'
from
 tag_date_value
where
 tag_id between 1 and 50
order by
 tag_id, tag_date;

select * into outfile 'tag_dat_value_002.dat' 
fields terminated by '|' optionally enclosed by '"'
lines terminated by '\r\n'
from
 tag_date_value
where
 tag_id between 51 and 100
order by
 tag_id, tag_date;

-- etc...

进口

以正确的顺序导入到表中!

start transaction;

load data infile 'tag_dat_value_001.dat' 
into table tag_date_value
fields terminated by '|' optionally enclosed by '"'
lines terminated by '\r\n'
(
tag_id,
tag_date,
value
);

commit;

-- etc...
2021-03-17