all*_*gan 10 mysql sql database-design query-optimization database-partitioning
我目前正在尝试提高MySQL表的SELECTS速度,并希望了解有关改进它的方法的任何建议.
表中有超过3亿条记录,表中有结构标记,日期,值.主键是标签和日期的组合键.该表包含大约600个唯一标签的信息,这些标签大多数包含平均约400,000行但可以在2000到超过1,100万行的范围内.
针对表运行的查询是:
SELECT date,
value
FROM table
WHERE tag = "a"
AND date BETWEEN 'x' and 'y'
ORDER BY date
Run Code Online (Sandbox Code Playgroud)
....如果有任何插入,很少.
我已经尝试按标签将数据划分为不同数量的分区,但这似乎没有增加速度.
花点时间阅读我的答案:(与您的卷相似)
0.02秒内扫描5亿行、1500万行范围。
然后将表引擎修改为 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;
Run Code Online (Sandbox Code Playgroud)
您可以考虑将以下内容作为主键:
primary key (tag_id, tag_date, value) -- added value save some I/O
Run Code Online (Sandbox Code Playgroud)
但前提是值不是某个 LARGE varchar 类型!
查询如前:
select
tag_date,
value
from
tag_date_value
where
tag_id = 1 and
tag_date between 'x' and 'y'
order by
tag_date;
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助 :)
编辑
哦忘了提 - 不要使用 alter table 将引擎类型从 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...
Run Code Online (Sandbox Code Playgroud)
进口
以正确的顺序导入回表中!
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...
Run Code Online (Sandbox Code Playgroud)