【问题标题】:MySQL Foreign Keys and Indexes optimizationMySQL 外键和索引优化
【发布时间】:2023-03-24 16:23:01
【问题描述】:

我有以下三个表:

users(约1000行)

    user_id | username | email | ....

events(大约 50 000 行,每天增加约 500 行)

    event_id | e_date | e_location | e_duration | ...

还有一个将用户链接到事件的表格:

users_events

    user_id | event_id

我在表 users_events 上设置了外键,以便在删除事件或用户时删除行,因此我在每个表中的每个 user_idevent_id 上都有一个索引 (PRIMARY)。

我对此设计有第二次猜测,因为在 events.event_id 上建立索引感觉很愚蠢,因为它是一个唯一 ID,其基数等于行数。

events.date 每年的最大基数为 365,events.location 的上限为 200 左右,因此对于索引而言,这些比 event_id 更合适。

有什么建议吗?

最常用的查询示例:

查找用户要去的事件:

    SELECT e.date, e.location FROM events e
    JOIN users_events ue ON ue.event_id = e.event_id
    JOIN users u ON u.user_id = ue.user_id
    WHERE user_id = 'currentuserid'

根据事件的特征判断事件是否已经存在:

    SELECT event_id FROM events
    WHERE date='eventdate'
    AND location='eventlocation'
    AND duration='eventduration'

【问题讨论】:

  • 没有理由你不能拥有多个索引,MySQL 只会选择它认为最适合该查询的一个。额外的索引确实意味着插入时间略有增加,但对于大多数应用程序而言,与 SELECT 的节省相比,这将是最小的。对于连接,唯一索引几乎​​可以得到。您的第一个查询将根据 user_id 从用户中选择一行(希望您有一个索引),使用 users_events.user_id 上的索引将其连接到 users_events,然后根据 events.events_id 上的索引将其连接到事件(希望主键)。
  • SHOW CREATE TABLE。看看你的 many:many 表是否看起来像 this

标签: mysql indexing foreign-keys


【解决方案1】:

如果users.user_idevents.event_id 已被定义为主键,则这些列已经有了索引。

users_events 表有两个索引(由您显式创建或由外键约束自动创建)。

第一个查询只需要上面提到的索引,不会受益于任何其他。

第二个查询将受益于events 表上的附加索引。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-03
    • 2016-05-18
    • 1970-01-01
    • 1970-01-01
    • 2010-11-01
    • 1970-01-01
    相关资源
    最近更新 更多