MySQL 自连接性能:事实还是糟糕的索引?
MySQL self join performance: fact or just bad indexing?
举个例子:我有一个数据库来检测访问者(机器人等),因为不是每个访问者都有相同数量的 'credential' 我做了一个 'dynamic' table 像这样:见fiddle:http://sqlfiddle.com/#!9/ca4c8/1(简化版)。
这个 returns 我用来收集关于每个配置文件(在另一个数据库中)的信息的配置文件 ID。根据配置文件类型,我使用不同的 name
子句(名称='something')(ei:主机名、ipAddr、userAgent、HumanId 等)查询 table。
我不是 SQL 方面的专家,但我熟悉索引、约束、主键、唯一键、外键等。根据我从这些搜索结果中看到的内容:
- Mysql Self-Join Performance
- How to tune self-join table in mysql like this?
- Optimize MySQL self join query
- JOIN Performance Issue MySQL
- MySQL JOIN performance issue
他们中的大多数人 评论 关于自连接的糟糕表现,但 答案 倾向于 缺失index 原因。
所以最后一个问题是:如果所有内容都已正确索引,那么自加入 table 是否会使其更容易出现性能不佳的情况?
附带说明,有关 table 的更多信息:可能与问题无关,但非常适合我的特定情况:
- 列标志用于标记要删除的记录,因为我在 php 中使用的用户对该数据库没有删除权限。抱歉,安全比性能更重要
- 我添加了 'type' ,它将与我从用户代理获得的信息一起使用。 (即:如果有任何东西(至少看起来是)机器人,我们将只搜索类型 5000。
- 列 'name' 不幸的是在主键(具有配置文件和类型)中索引了一个 varchar。
- 我尝试在 SELECT 查询中使用尽可能多的 INT 和过滤 (WHERE) 以减少最终的性能损失(如果这很重要的话)
- 如果需要,我愿意研究和调整这件事,除非在 mysql 方面有高背景的人告诉我这真的不是一件好事。
这是我正在开发的一个大项目,所以我现在无法用数百万条记录对其进行测试,但我想知道随着它的增长性能是否会成为问题。任何输入、链接、参考、文档或测试程序(可能在评论中)将不胜感激。
A self-join 与连接两个不同的表没有什么不同。优化器将选择一个 'table',通常基于 WHERE
,然后对另一个进行嵌套循环连接。在您的情况下,您已经通过 LEFT
暗示它应该只能以一种方式工作。 (优化器将忽略 if 它认为不需要它。
您的钥匙已找到 Fiddle。
真正的问题是 "Entity-Attribute-Value",这是一种在表格中布置数据的混乱方式。您的查询似乎是在说“找到具有特定属性对的(限制 1)profile
(实体)(name = Googlebot AND
addr = ...)。
如果有两列(名称和地址)和一个 "composite" INDEX(name, addr)
.
会更容易、更快
我建议对 common "attributes" 执行此操作,然后将其余内容放入带有 JSON 字符串的单个列中。参见 here。
举个例子:我有一个数据库来检测访问者(机器人等),因为不是每个访问者都有相同数量的 'credential' 我做了一个 'dynamic' table 像这样:见fiddle:http://sqlfiddle.com/#!9/ca4c8/1(简化版)。
这个 returns 我用来收集关于每个配置文件(在另一个数据库中)的信息的配置文件 ID。根据配置文件类型,我使用不同的 name
子句(名称='something')(ei:主机名、ipAddr、userAgent、HumanId 等)查询 table。
我不是 SQL 方面的专家,但我熟悉索引、约束、主键、唯一键、外键等。根据我从这些搜索结果中看到的内容:
- Mysql Self-Join Performance
- How to tune self-join table in mysql like this?
- Optimize MySQL self join query
- JOIN Performance Issue MySQL
- MySQL JOIN performance issue
他们中的大多数人 评论 关于自连接的糟糕表现,但 答案 倾向于 缺失index 原因。
所以最后一个问题是:如果所有内容都已正确索引,那么自加入 table 是否会使其更容易出现性能不佳的情况?
附带说明,有关 table 的更多信息:可能与问题无关,但非常适合我的特定情况:
- 列标志用于标记要删除的记录,因为我在 php 中使用的用户对该数据库没有删除权限。抱歉,安全比性能更重要
- 我添加了 'type' ,它将与我从用户代理获得的信息一起使用。 (即:如果有任何东西(至少看起来是)机器人,我们将只搜索类型 5000。
- 列 'name' 不幸的是在主键(具有配置文件和类型)中索引了一个 varchar。
- 我尝试在 SELECT 查询中使用尽可能多的 INT 和过滤 (WHERE) 以减少最终的性能损失(如果这很重要的话)
- 如果需要,我愿意研究和调整这件事,除非在 mysql 方面有高背景的人告诉我这真的不是一件好事。
这是我正在开发的一个大项目,所以我现在无法用数百万条记录对其进行测试,但我想知道随着它的增长性能是否会成为问题。任何输入、链接、参考、文档或测试程序(可能在评论中)将不胜感激。
A self-join 与连接两个不同的表没有什么不同。优化器将选择一个 'table',通常基于 WHERE
,然后对另一个进行嵌套循环连接。在您的情况下,您已经通过 LEFT
暗示它应该只能以一种方式工作。 (优化器将忽略 if 它认为不需要它。
您的钥匙已找到 Fiddle。
真正的问题是 "Entity-Attribute-Value",这是一种在表格中布置数据的混乱方式。您的查询似乎是在说“找到具有特定属性对的(限制 1)profile
(实体)(name = Googlebot AND
addr = ...)。
如果有两列(名称和地址)和一个 "composite" INDEX(name, addr)
.
我建议对 common "attributes" 执行此操作,然后将其余内容放入带有 JSON 字符串的单个列中。参见 here。