【问题标题】:Query to fetch old data (imported from identical dbs) and new data using joins查询以获取旧数据(从相同的数据库导入)和使用连接的新数据
【发布时间】:2016-03-22 13:18:40
【问题描述】:

简介:我已从具有相同数据库的现有应用程序中导入数据。有很多表,所以不可能用新的 ID 更新数据。每个表的现有主键,例如serviceprovidersp_id。对于所有表,我添加了一个新的主键 id。我需要从这些表中获取新旧数据(导入完成后)。为了获取旧数据,我使用旧的主键/外键并比较 database_id 以获取要从导入位置加入的表。新数据只使用新的主键id。我知道它是否是新数据,因为旧主键的值 0.

select serviceprovider.* from serviceprovider sp
inner join services ss on ((sp.id = ss.sp_id) AND (ss.ss_id = 0))
OR ((sp.sp_id = ss.sp_id) AND (ss.ss_id <> 0) AND (sp.database_id=ss.database_id))

我已经构建了这个查询,随着数据的增加,它变得非常慢。最初它运行良好,但当我从旧数据库导入数据时,它几乎停止工作。你可以猜到我需要加入更多的表来获取完整的数据。所有表都使用相同的连接机制。我正在使用 MySQL。可以重新构造查询以获得更好的性能吗?

【问题讨论】:

  • 新增记录时database_id的取值是多少?
  • 它从 1 到 5。如果我从数据库 1 导入了父表和子表的数据,那么它们的所有记录中的 database_id 都会为 1
  • 对于非导入记录,它们是 0 还是 NULL?
  • 数据库代表公司分支机构。它从 1 变为 5。如果我从数据库 1 导入了父表和子表的数据,那么它们的所有记录中的 database_id 都将带有 1。如果有新记录,database_id 继续保持 1 到 5 之间的值

标签: mysql database join


【解决方案1】:

这个查询不应该太重,请考虑在所有被连接的表上添加一个索引:

serviceprovider(id,sp_id,database_id)

services(sp_id,ss_id,database_id)

这应该会加快查询速度。

您也可以尝试使用 EXISTS() 而不是内部连接来重建您的查询:

select serviceprovider.* from serviceprovider sp
WHERE EXISTS(select 1 from services ss
             where ((sp.id = ss.sp_id) AND (ss.ss_id = 0))
                    OR ((sp.sp_id = ss.sp_id) AND (ss.ss_id <> 0) AND (sp.database_id=ss.database_id)))

也许它会跑得更快。

编辑:让我们尝试另一种方法,两个选择和一个联合,而不是这个 OR 条件:

select serviceprovider.* from serviceprovider sp
inner join services ss on (sp.id = ss.sp_id AND ss.ss_id = 0)
UNION ALL
select serviceprovider.* from serviceprovider sp
inner join services ss on(sp.sp_id = ss.sp_id AND ss.ss_id <> 0 AND sp.database_id=ss.database_id)

【讨论】:

  • 感谢您的回复。正如我提到的,有更多的连接,但这个主要连接似乎是瓶颈。我已经为所有表添加了索引。您的查询运行速度比现有查询慢 3 倍。
  • 正如预期的那样,联合解决方案奏效了。关键是将条件一分为二。获取的数据越少,差异就越小,但是当我用更多的数据对其进行测试时,性能变得越来越好。我之前确实尝试过 union 但不记得确切的版本以及为什么它不起作用。谢谢
猜你喜欢
  • 2015-01-06
  • 2014-07-25
  • 1970-01-01
  • 1970-01-01
  • 2018-04-14
  • 2021-09-01
  • 1970-01-01
  • 2020-10-22
  • 1970-01-01
相关资源
最近更新 更多