代码之家  ›  专栏  ›  技术社区  ›  O. Jones

基于效率的MySQL索引和主密钥设计

  •  0
  • O. Jones  · 技术社区  · 15 年前

    我有一个中等规模的记录集合——大约2000万条——需要加载到MySQL中以用于数据分析。这些恰巧是人们参观地方的记录。它们由三个数据项唯一标识:

    • 地点-独特的内景
    • person-一个字符串,有时是数字,有时是字母数字,例如ab12345678
    • 访问-类似于人

    我对个人和访问字段内容没有任何控制权,因为这些内容是由不同的地方提供的,并且每个地方都做自己的事情。

    我可以通过匹配地点和人来查找一个人的所有记录,通过匹配这三个记录来查找单个记录。

    我可以在MySQL中通过创建这样的表使其正常工作:

    CREATE TABLE ENCOUNTER (
      PLACE int(11) NOT NULL,
      PERSON varchar(255) NOT NULL,
      VISIT varchar(255) NOT NULL,
      ARRIVAL_TIME datetime DEFAULT NULL,
      DEPARTURE_TIME datetime DEFAULT NULL,
      EVENT varchar(255) NOT NULL,
      PRIMARY KEY (PLACE,PERSON,VISIT)
    ) ENGINE=MyISAM DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC;
    

    我使用myisam是因为我不需要这个表上的ACID事务完整性;它用于统计报告,所以如果它是一行或两行过时的,那就没问题了。

    该表经常会被更新击中,这些更新只会改变其中一个字段,比如离开时间。这些更新的频率很可能是新行插入的两倍。不需要更新地点、人员或访问标识符。

    以下是一些问题:

    使用一个索引和键列来连接地点/个人/访问信息,我的性能会更好吗?

    对于varchar索引,我需要多少命中率?是否值得尝试将它们约束到固定长度的字段?

    收集到的智慧还有其他的建议吗?

    谢谢。

    2 回复  |  直到 15 年前
        1
  •  0
  •   longneck    15 年前

    你的索引是正确的。你不能做得更好。

    这是一个完美的、不明显的使用分区的机会。我觉得你所有的分析都是基于地点的。如果是,那么根据place列创建一个哈希分区,如下所示:

    ALTER TABLE encounter PARTITION BY KEY(place) PARTITIONS 12;
    

    这将使您的查询更快,因为MySQL知道在一个地方进行分析时,它可以跳过1/12的行。

        2
  •  0
  •   Quassnoi    15 年前

    我可以通过匹配地点和人来查找一个人的所有记录,通过匹配这三个记录来查找单个记录。

    如果要搜索某人访问过的所有位置,则需要在 (person, place) .

    对于varchar索引,我需要多少命中率?是否值得尝试将它们约束到固定长度的字段?

    一次关键的打击也需要同样的时间 INT VARCHAR 记录。

    一个关键的失误对 瓦卡尔 领域。