【问题标题】:Add an index to composite primkary keys in Mysql在 Mysql 中为复合主键添加索引
【发布时间】:2021-05-09 10:11:45
【问题描述】:

假设我有三个表:

客户(CustomerID、出生日期、城市、地址、电话、销售、 性)

购买(CustomerIDItemID日期

商品(商品ID、描述、颜色、价格、供应商、库存)

所以,cutomerID 是 Customer 的主键,ItemID 是 Item 的主键,(CustomerID, ItemID, Date) 是 Purchase 表的复合主键。

据我所知,没有必要在主键上应用索引(在这种情况下,表 1 的 customerID 和表 3 的 ItemID),因为 mysql 会自动执行此操作。

复合主键呢?

我应该在复合 pk(CustomerID、ItemID、Date)上应用唯一索引吗?或者最好在三列上添加单独的非唯一索引(因此,customerID 上的非唯一索引、ItemID 上的非唯一索引和 dateID 上的非唯一索引)?

考虑到这三个表的数据非常丰富,需要很多连接

【问题讨论】:

    标签: mysql sql database indexing


    【解决方案1】:

    主键具有关联的索引。这不取决于您的主键是否是复合的。

    来自docs

    表的主键代表您在最重要的查询中使用的列或列集。它有一个关联索引,可实现快速查询性能。

    如果您有对Purchase.Date 字段设置条件的查询,那么您可能仅从该字段上的非唯一索引中受益。但是这个索引在实际查询中是否会用到,必须用explain来验证。这将为您提供最终确认是否确实使用了该索引。如果您发现它没有被使用,则将其删除,因为索引还会为相关表的每次 DML 更新带来额外的开销。

    【讨论】:

    • 因此,例如,我必须使用“customerID”在客户和购买之间进行许多连接,这并不建议我在购买表中的 CustomerID 上添加非唯一索引?
    • 不,customerID 是复合索引的第一个字段,因此索引可以用于这样的连接。但同样,数据库引擎将在分析查询和确定执行计划时做出决定。
    【解决方案2】:

    Purchase 上的复合主键基于 (CustomerID, ItemID, date) 上的唯一索引。

    这不等同于 (CustomerID)(ItemID)(Date) 上的单独索引。

    您需要单独的索引吗?好吧,对于从PurchasesCustomersItems 的任何连接,Purchases 上的索引不是很重要——重要的是引用表上的主键。

    什么时候需要二级索引?连接可能更少,过滤更多。特别是,我可以想象对date 进行过滤会很重要,并且可能值得一个索引。

    此外,如果您有诸如“获取所有尚未购买的物品(例如在两个日期之间)”之类的查询,通常会表达为:

    select i.*
    from items i
    where not exists (select 1 from purchases p where p.itemId = i.itemId);
    

    在这种情况下,Purcahses(itemId) 上的索引会很有帮助。

    【讨论】:

      【解决方案3】:

      不,主键会自动编入索引

      表的主键代表您在最重要的查询中使用的列或列集。它有一个关联的索引,以实现快速的查询性能。

      https://dev.mysql.com/doc/refman/8.0/en/primary-key-optimization.html

      【讨论】:

        猜你喜欢
        • 2019-04-10
        • 2011-08-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多