【问题标题】:Efficient indexes for lookup table查找表的高效索引
【发布时间】:2020-01-16 02:10:09
【问题描述】:

我试图了解在查找表上分配索引的正确方法。给定以下表格和示例查询,查找表最有效的主/附加索引是什么?

表格:项目(id、标题等)

表格:类别(id、标题等)

表格:查找(category_id、item_id、类型等)

SELECT * FROM items 
    INNER JOIN lookup ON
        lookup.item_id=items.id AND lookup.type="items" 
    INNER JOIN categories ON 
        categories.id=lookup.category_id;

【问题讨论】:

    标签: mysql sql database performance indexing


    【解决方案1】:

    映射表没有 auto_incr id。

     PRIMARY KEY(type, item_id, category_id),
     INDEX(category_id, type, item_id)
    

    对于第二个索引,从一个类别转到一个项目时是否需要type?如果没有,请忽略它。

    更多:http://mysql.rjweb.org/doc.php/index_cookbook_mysql#many_to_many_mapping_table

    【讨论】:

    • 谢谢!澄清一下:我有多种数据类型,多种分类法。每个分类都有一个查找表,可以将其连接到一种或多种数据类型,因为可能存在与关联本身相关的数据的其他字段。在某些情况下,许多数据类型支持一种分类法,而另一些只支持几种。出于这个原因,“类型”字段可能会过滤很多,但过滤掉另一个。这里的回答似乎是一致的。但是,我会注意到,当此查询上方有两个索引时,总是更喜欢后一个。不知道为什么或是否值得关注。
    【解决方案2】:

    除了连接谓词之外,您的查询只有一个过滤前置词 (lookup.type = "items")。如果此谓词具有良好的选择性(即它选择 5% 或更少的行),那么您应该将其用作索引的第一列。我会这样做:

    create index ix1 on lookup (type, item_id, category_id)
    

    如果表itemscategories 上的id 列代表主键,则无需执行其他操作。

    引擎可能会使用索引读取查找表,然后使用它们的 PK 索引读取其他两个表。

    【讨论】:

      【解决方案3】:

      对于这个查询:

      SELECT *
      FROM items i JOIN
           lookup l
           ON l.item_id = i.id AND l.type = 'items' JOIN 
           categories c
           ON c.id = l.category_id;
      

      最好的索引可能是:

      • lookup(type, item_id)
      • categories(id)(如果id 是主键,可能已经存在)
      • items(id)(如果id 是主键,可能已经存在)

      在某些情况下,这可能不是一个很大的改进,特别是如果大多数 lookup() 行都有一种“项目”类型。

      【讨论】:

        猜你喜欢
        • 2019-07-30
        • 2015-03-21
        • 1970-01-01
        • 2013-10-17
        • 2023-01-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多