2016-03-08 117 views
0

我有以下三个表:MySQL的外键和索引优化

users(约1000线)

user_id | username | email | .... 

events(约50万行,并在5〜50天增加)

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' 

OR

发现,如果一个事件是根据它的特性已经存在:

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

没有理由你不能拥有多个索引,MySQL只会选择它认为最适合该查询的那个索引。额外的索引确实意味着INSERT时间略有增加,但对于大多数应用来说,与SELECT中的节省相比将是最小的。对于一个联接,一个独特的索引是非常好的,因为它可以得到。你的第一个查询将基于user_id从用户中选择一行(希望你有一个索引),使用users_events.user_id上的索引将它加入到users_events中,然后根据events.events_id上的索引将它加入到事件中(希望一个主键)。 – Kickstart

+0

'SHOW CREATE TABLE'。看看你的很多:很多表看起来像[this](http://mysql.rjweb.org/doc)。PHP/index_cookbook_mysql#many_to_many_mapping_table)。 –

回答

0

如果已将这些列定义为主键,则您已在users.user_idevents.event_id上有索引。

users_events表有两个索引(可以由您自己创建,也可以由外键约束自动创建)。

第一个查询只需要从上面提到的索引中获得,并且不会从任何其他获益。

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