两列“OR”查询速度与单列“DOUBLE THE ROWS”查询速度

时间:2013-11-27 00:12:02

标签: mysql sql optimization

所以假设我们有一个包含多个列的表,我们在两个列上编制索引: Player 1 Player 2

GAME   PLAYER 1    PLAYER 2   ...
====   ========    ========  
1      John        Dan
2      Carl        William
3      Carl        John
...

仅在单个列上建立索引的备用表结构: Player 1 (并且有两倍的行):

GAME   PLAYER 1    PLAYER 2   ...
====   ========    ========  
1      John        Dan
1      Dan         John
2      Carl        William
2      William     Carl
3      Carl        John
3      John        Carl
...

我想查询John所玩的所有游戏。哪种表结构/方法更好?

需要考虑的事项:

  • 这是一个简化版本,必须考虑到这些表将包含至少100个数千行,并且查询中将有多个连接。
  • 播放器列上会有连接,因此使用带有“OR”/“UNION”的TWO COLUMN方法也会使一些连接加倍。
  • 单列方法需要游戏列上的“GROUP BY”。
  • 我们不想耗尽内存,查询应该继续在内存中运行!
  • TWO COLUMN方法已经变慢,现在依赖于Mysql的内置缓存来保持其以舒适的速度运行。我正在考虑采用单柱方法,但不确定后果。
  • 另一种解决方案是使用播放器游戏(外键)增加一个表。

2 个答案:

答案 0 :(得分:2)

最好将表格标准化。为具有id的玩家准备一张桌子,并将外键即player_id放在游戏桌上。 如果你在player_ids上设置索引,它会更好地扩展。 它还将使用户的未来更改变得更加容易。

答案 1 :(得分:2)

在这个简单的情况下,对于两列都有一个索引,无论如何,使用索引,你的表大小基本上都会翻倍。

如果有超过2个玩家列,则第二种方法的行数将等于玩家列数的游戏数量,而索引方法将只需将游戏数量乘以指数空间的玩家列数。

无论哪种方式,为了提高性能,最好将ID替换为引用玩家的ID。另一个表中的名字。

此外,在我看来可能有一种更简单的方法。

GAME   PLAYER
====   ========
1      John
1      Dan
2      Carl
2      William
3      Carl
3      John

无需复制数据。在这里你仍然可以检索游戏1中的所有玩家,现在你可以更轻松地检索每个玩家所在的游戏。在这里,你只需要一个索引。但是,这可能会使其他一些查询复杂化。