2

我从这个问题开始:我的大型 mysql 表注定要失败吗?

我从那个问题中找到的答案是令人满意的。我有一个包含 2200 万行的表,我希望将其增加到大约 1 亿行。这时候的表minute_data结构是这样的: 在此处输入图像描述

我遇到的一个问题如下。我需要执行这个查询:

select datediff(date,now()) from minute_data  where symbol = "CSCO" order by date desc limit 1;

当表包含值“CSCO”时,这非常快(< 1 秒)。问题是,有时我会查询一个不在表中的符号。当我为 symbol = "ABCD" 执行这样的查询时:

select datediff(date,now()) from minute_data  where symbol = "ABCD" order by date desc limit 1;

然后查询需要很长时间......就像永远(180秒)。

我可以解决这个问题的一种方法是在执行查询之前确保表包含我正在寻找的符号。我发现执行此操作的最快方法是使用以下查询,我只需要使用它来检查表是否minute_data包含我正在寻找的符号。基本上我只需要它返回一个布尔值,这样我就知道符号是否在表中:

select count(1) from minute_data where symbol = "CSCO";

这个查询需要 30 多秒才能返回 1 个值,这对我来说太长了,因为上面的查询实际上返回一个datediff计算只需要不到 1 秒。

symbol列是 pri 键的一部分,我认为它应该能够很快找出是否存在值。

我究竟做错了什么?有没有一种快速的方法来做我想做的事?我应该更改数据结构以优化性能吗?

谢谢你!

更新

我想我找到了解决这个问题的好方法。从 LastCoder 下面的回答中,我做了以下事情:

1) 创建了一个新表minute_data_2,其名称与minute_data.

2)ALTER TABLE minute_data_2 ADD PRIMARY KEY(符号,日期);

3) INSERT IGNORE INTO minute_data_2 SELECT * FROM minute_data;

4) 删除表分钟数据;

5) 将 minute_data_2 重命名为 minute_data

现在,我看到上面描述的相同查询的速度非常快,耗时超过 180 秒,现在在 0.001 秒内完成。惊人。

4

2 回答 2

2

您是否尝试使用 EXISTS (...)

select datediff(date,now()) from minute_data  
where EXISTS(SELECT * FROM minute_data WHERE symbol = "CSCO") 
AND symbol = "CSCO" order by date desc limit 1;

即使符号是主键,但似乎您也将时间戳作为 PK,这让我认为您使用的是 COMPOSITE pk,这意味着排序是按时间戳然后符号。如果您所拥有的只是一个以时间戳为第一的复合索引,则您可能希望在符号上放置单独的索引。

于 2013-03-25T12:53:26.507 回答
0

我认为最好创建一个名为的表symbols并在表中添加对该表的引用minute_data

符号:
symbol_id (INT, Primary Key, Auto Increment)
symbol_text (VARCHAR)

minute_data :
key_col (BIGINT, Primary Key, Auto Increment)
symbol_id (INT, Index)
other_field

使用 InnoDB 作为表类型来添加引用。

尽量避免重复输入到您的表中..

于 2013-03-25T12:56:52.737 回答