13

我正在使用 mySQL 建立一个股票期权数据库。大约有 330,000 行(每行是 1 个选项)。我是 SQL 新手,所以我试图确定选项符号(从 4 到 5 个字符不等)、股票代码(从 1 到 5 个字符不等)、公司名称(从 5 到 60 不等)等字段类型人物)。

我想优化速度。两者都创建数据库(随着新的价格数据出现,每 5 分钟发生一次——我没有实时数据馈送,但它接近实时,因为我得到了一个包含 330,000 行的新文本文件交付给我每 5 分钟一次;这个新数据完全取代了以前的数据),同时也提高了查找速度(将有一个基于 Web 的前端,许多用户可以在其中运行即席查询)。

如果我不关心空间(因为数据库的生命周期是 5 分钟,并且每行可能包含 300 个字节,所以整个事情可能是 100MB)那么构建字段的最快方法是什么?

实际上,对于数字字段同样的问题:int(11) 和 int(7) 之间是否存在性能差异?对于查询和排序,一种长度是否比另一种更好?

谢谢!

4

5 回答 5

34

在 MyISAM 中,制作固定宽度的记录有一些好处。VARCHAR 是可变宽度。CHAR 是固定宽度的。如果您的行只有固定宽度的数据类型,那么整行都是固定宽度的,并且 MySQL 在计算该表中行的空间需求和偏移量时获得了一些优势。也就是说,优势可能很小,并且几乎不值得拥有固定宽度的填充 CHAR 列(其中 VARCHAR 可以更紧凑地存储)所带来的其他成本(例如缓存效率)所抵消的微小收益。

它变得更有效的断点取决于您的应用程序,除非您测试两种解决方案并使用最适合您的应用程序使用的数据的一种,否则这是无法回答的。

关于 INT(7) 与 INT(11),这与存储或性能无关。一个常见的误解是 MySQL 对 INT 类型的参数与数据大小有关——它没有。MySQL 的 INT 数据类型始终为 32 位。括号中的参数是指使用 ZEROFILL 显示值时要填充的位数。例如,INT(7) 将显示 0001234,而 INT(11) 将显示 00000001234。但这种填充仅在显示值时发生,而不是在存储或数学计算期间发生。

于 2008-12-08T18:07:17.637 回答
6

If the actual data in a field can vary a lot in size, varchar is better because it leads to smaller records, and smaller records mean a faster DB (more records can fit into cache, smaller indexes, etc.). For the same reason, using smaller ints is better if you need maximum speed.

OTOH, if the variance is small, e.g. a field has a maximum of 20 chars, and most records actually are nearly 20 chars long, then char is better because it allows some additional optimizations by the DB. However, this really only matters if it's true for ALL the fields in a table, because then you have fixed-size records. If speed is your main concern, it might even be worth it to move any non-fixed-size fields into a separate table, if you have queries that use only the fixed-size fields (or if you only have shotgun queries).

In the end, it's hard to generalize because a lot depends on the access patterns of your actual app.

于 2008-12-08T17:21:26.793 回答
4

鉴于您的系统限制,我建议使用 varchar,因为您对数据所做的任何事情都必须适应您放置的任何填充以使用固定宽度的字符。这意味着在某个地方有更多代码需要调试,并且更容易出错。话虽如此:

应用程序的主要瓶颈是由于每五分钟删除和重新创建数据库。您不会从选择 char 而不是 varchar 之类的微增强功能中获得太多性能优势。我相信您有一些更严重的架构问题需要解决。- 公主

我同意上述评论。在您担心 char 和 varchar 之间的区别之前,您的架构中有更大的鱼要炸。一方面,如果您有一个 Web 用户尝试运行临时查询并且数据库正在重新创建过程中,您将收到错误(即“数据库不存在”或只是“超时”类型的问题)。

我建议您(至少)为最新的报价数据(带有时间戳)、股票代码表和历史表构建(至少)一个报价表。您的网络用户将查询股票代码表以获取最新数据。如果您的 5 分钟文件中出现一个不存在的符号,那么在将新信息发布到报价表之前让导入脚本创建它就足够简单了。所有其他都得到更新,查询默认为当天的数据。

于 2008-12-08T18:08:25.000 回答
1

我绝对不会每次都重新创建数据库。相反,我会执行以下操作:

  • 读入更新/快照文件并根据每一行创建一些对象。
  • 为每一行获取符号/选项名称(唯一)并将其设置在数据库中

如果是我,我也会有一个所有符号和当前价格数据的内存缓存。

价格数据永远不是 int - 您可以使用字符。

公司名称可能不是唯一的,因为特定公司有很多选择。那应该是一个索引,您可以仅使用公司的 id 来节省空间。

正如其他人也指出的那样-您的网络客户端不需要访问实际的数据库并进行查询-您可能只需访问缓存即可。(尽管这实际上取决于您向客户公开哪些表和数据以及他们想要哪些数据)

拥有其他用户的查询访问权限也是不继续删除和创建数据库的原因。

于 2009-04-07T19:10:25.020 回答
1

还要记住,创建数据库取决于您使用的任何实际数据库实现。如果您曾经从 MySQL 移植到 Postgresql,您会发现一个非常令人不快的事实,即在 postgresql 中创建数据库是一个相对非常缓慢的操作。例如,它比读取和写入表行慢几个数量级。

看起来有一个应用程序设计问题需要先解决,然后再优化性能以选择适当的数据类型。

于 2010-01-04T15:30:00.027 回答