MySQL自联接性能:事实还是只是糟糕的索引?

时间:2017-02-09 06:11:47

标签: mysql performance join indexing entity-attribute-value

作为一个例子:我有一个数据库来检测访问者(机器人等),因为不是每个访问者都有相同数量的'凭证',我就像这样制作了一个“动态”表:见小提琴:{{3 (简化版)。

这将返回我用于收集有关每个配置文件(在另一个数据库中)的信息的配置文件ID。根据配置文件类型,我使用不同的name子句(name ='something')查询表(ei:hostname,ipAddr,userAgent,HumanId等)。

我不是SQL的专家,但我熟悉索引,约束,主要,唯一,外键等等。从我从这些搜索结果中看到的内容:

他们中的大多数都有评论关于自我加入的糟糕表现,但答案倾向于选择缺失索引原因。

所以最后一个问题是:假设所有内容都被正确编入索引,自我加入表会使其更容易出现糟糕的性能吗?

在旁注中,有关该表的更多信息:可能与该问题无关,但在我的特定情况下具有良好的背景:

  • 列标志用于标记要删除的记录,因为我在php中使用的用户对此数据库没有DELETE权限。对不起,安全性比性能更重要
  • 我添加了'type',它将包含我从用户代理处获得的信息。 (即:如果有任何东西(至少似乎是)机器人,我们只会搜索5000型。
  • 不幸的是,列'name'是主键中的varchar索引(带有配置文件和类型)。
  • 我尝试在SELECT查询中使用尽可能多的INT和过滤(WHERE)以减少最终的性能损失(如果这甚至很重要)
  • 如果需要的话,我愿意学习和调整这个东西,除非mysql背景很高的人告诉我这不是一件好事。

这是我正在开发的一个大项目,所以我现在无法用数百万条记录进行测试,但我想知道随着这种情况的发展,性能是否会成为一个问题。任何输入,链接,参考,文档或测试程序(可能在评论中)将不胜感激。

1 个答案:

答案 0 :(得分:1)

自联接与加入两个不同的表没什么不同。优化器将选择一个'表',通常基于WHERE,然后在另一个中执行嵌套循环连接。在您的情况下,您已经通过LEFT暗示它应该只采用一种方式。 (优化器会忽略如果它认为不需要它。

找到那个小提琴的钥匙。

真正的问题是“实体 - 属性 - 价值”,这是一种在表格中布置数据的混乱方式。您的查询似乎在说“查找具有特定属性对的(限制1)profile(实体)”(名称= Googlebot AND addr = ...)。

拥有两列(name和addr)和一个“复合”INDEX(name, addr)会更容易,也更快。

我建议为 common “attributes”执行此操作,然后将其余部分放入带有JSON字符串的单个列中。请参阅here