优化表结构以便随时间记录数据

时间:2015-04-02 18:48:18

标签: php mysql

这是一个有10个产品供稿的网站。 Feed每天都会导入多次。在每个导入阶段,我想在表中保存每个项目的skuprice(如果价格下降超过10%,请通过邮件提醒)。

目前我存储的数据如下:

primary_key   sku     price datetime
1             XYX     1     2015-04-02 20:10:59  
2             ZYZ     2     2015-04-02 20:10:59
3             XYX     2     2015-04-03 20:10:59
4             XYX     0.5   2015-04-04 20:10:59

对于sku XYX,价格演变为1 - > 2 - > 0.5。在这个阶段,我想发一封警告邮件。我知道该怎么做。问题是,对于每个产品Feed,表增长约50.000行。尝试通过以下查询获取结果时:

SELECT sku,
       group_concat(cast(price as char(10)) separator '->') 
FROM table1 
GROUP BY sku 
ORDER BY datetime

......至少需要5秒钟。时间过后,表格将会有更多行,查询时间也会增加。我可以删除超过4天的记录(因为周末)。

我正在考虑制作如下表格:

id    sku    price
1     XYX    1->2->3->2.3
2     VZV    5->6->5->5.5

...但是在这种情况下,我不会“能够”按日期删除旧记录,而价格列必须是text / blob,这可能会对查询时间的组合产生很大影响(php + mysql )。

什么是最快的运行查询?

谢谢!

3 个答案:

答案 0 :(得分:2)

group_concat存在一个众所周知的性能问题,但使用DISTINCT并非您的情况。

尝试添加索引price列:

ALTER TABLE `products` ADD INDEX `price` (`price`)

由于是使用group_concat的人并运行查询以检查性能是否更好。另外,我会关注@symcbean建议。

另一个解决方案是有两个单列索引,如@ user2411276所示。

如果您有一个包含两列的索引,则查询可能会更快(您应该测量)。两列索引也可以用作单列索引,但仅适用于首先列出的列。

有时在(A,B)上有索引,在(B)上有另一个索引。这会使用其中一个或两个进行查询,但也会占用更多磁盘空间。

选择索引时,还需要考虑插入,删除和更新的影响。 更多索引,更新速度更慢,所以开始测试并祝你好运!

答案 1 :(得分:1)

在sku和价格列上创建索引:

alter table <table_name> add INDEX indx_sku (sku,price);

答案 2 :(得分:1)

虽然存在将多个值存储在同一行(多个字段)中的论点,但大多数人会同意,当正确规范化的解决方案无法满足您的需求时,这应该是最后的手段,但我怀疑任何有重要经验的人关系数据库会认为将多个值放在同一个字段中是个好主意。

您现在遇到性能问题吗?如果是,则发布另一个问题,包括查询,架构和解释计划。

您在此处向我们展示的查询将读取数百万行,因此,是的,这需要时间。优化模式/处理可能有很多空间,例如:只在SKU的价格发生变化时才添加记录,但这可能会对其他地方产生很大的影响。