表索引建议

时间:2012-03-21 10:45:02

标签: mysql sql optimization database-performance

我正在处理多对多的关系,并且我阅读了一些建议不要使用主键或索引的文档。

我很想听听您对我的数据库的看法。

它只有2列,每列都有bigint无符号值(数百万行)。

示例:

012934567865434            10923883093280921
012984902348202            10923812122220677
012930245820556            77777883093123124
984017133446720            76567883093098765
098523467527659            09876583093890456

在第1列中,每个值最多重复100次,如果它们重复,则它们是一个接一个。所以模式是:

value1
..value1 repeated 100 times
value2
..vlaue2 repeated 20 times
value3
value3 repeated 60 times

在第2列中,值有时会重复,但重复不会一个接一个地分组。所以它们可能会有数百万行。

有关如何优化的任何建议:

  • 创建索引?
  • 使用主键?
  • 按升序重新排序列?如果是的话多久一次?
  • 你能想到的任何其他想法都会加速它!
    等。

3 个答案:

答案 0 :(得分:1)

当你有多对多的关系时,通常的解决方案是实现三个表table1(在你的例子中== column1)和table2(== column2)将包含<关系中的strong>唯一值(以及必要时的主键),table3关联两组键。 table1table2table3的关系将是一对多的

例如:

<强>表1
id1(PK)
COL1
COL2
......(更多栏目)

表2
id2(PK)
可口可乐
COLB
......(更多栏目)

表3
ID1
ID2
..在表3中,对(id1,id2)将形成一个唯一的密钥

在您的情况下,table1将包含column1和table2中的唯一值,而其中table3将包含唯一的值对。

答案 1 :(得分:1)

没有正确性,性能无关紧要。既然你说(在评论中)......

  

“第1栏+第2栏中特定值的组合在表格中不能存在多次。”

... 正确要做的是将两个字段放在一个复合键中。

有效地强制执行此密钥,您需要一个索引。所以,你至少需要一个索引。问题是哪个指数?这取决于您希望查询数据的“方向”:

  • 如果您需要有效地回答“对于给定的value1 value2与之相关的问题”,则索引应为{value1, value2}
  • 如果您需要有效地回答“对于给定的value2 value1与之相关的问题”,则索引应为{value2, value1}
  • 如果您需要有效地回答这两个问题,那么您需要两个索引(但要注意您在群集表中为二级索引支付的价格 - 请参阅{{3}中的“群集的缺点” })。
BTW,如果您没有明确指定任何PK或UNIQUE约束,InnoDB将生成隐藏的PK。这是集群所必需的。


在支持索引压缩的DBMS(例如Oracle)上,当索引的前沿中有许多重复值时,可以节省空间。存储很便宜,但这不是重点 - 较小的数据意味着有效的“更大”缓存。

唉,MySQL不是这样的DBMS。


在一个更哲学的说明中,除非你自己指定,否则没有“订单”这样的东西。

  • 在基于堆的表(MyISAM)中,堆中行的物理顺序大致遵循INSERTions的顺序,但从客户角度来看,最好将其视为随机。
  • 群集表(InnoDB)本质上是一个根据群集密钥(即PK)对其叶子进行排序的树。但是,除非指定ORDER BY。
  • ,否则无法保证查询结果顺序
  • 索引在某种意义上是“有序”的,但即使使用索引,也不会以任何特定顺序获得查询结果,除非指定ORDER BY。

在所有3种情况下,您需要ORDER BY来保证以任何特定顺序返回查询结果。

答案 2 :(得分:0)

向表中添加索引会加快读取速度(特别是在连接表时),但会降低写入速度。通常,读取性能可能比写入性能具有更高的优先级,因为记录可能比写入更频繁地读取 - 异常往往是日志表。

除了性能之外,设置索引的另一个原因是防止重复。

因此,如果您的表可能经常被写入但很少阅读,您可以确定不会插入任何重复的列组合,您可能不应该向其中添加任何索引。表

但是,如果您的表可能不经常写入但经常阅读,您希望数据库确保不能插入任何重复的列组合,那么您应该设置适当的索引。