MySQL:如何确定表A和表B中的哪些行在线性时间内被表C中的行引用?

MySQL:如何确定表A和表B中的哪些行在线性时间内被表C中的行引用?,mysql,reference,performance,count,Mysql,Reference,Performance,Count,我正在使用一个设计拙劣的数据库,我不能自由地进行重组。在这个数据库中,有三个表,我们称它们为‘companiesA’、‘companiesB’和‘items’,它们涉及我需要优化的查询companiesA'和companiesB'描述公司的方式相同,因为列值相同,但它们代表两个不同的公司组,并且具有不同的列名。本质上,ID和公司名称列在“companiesA”中是“aID”和“aName”,在“companiesB”中是“idB”和“nameB”items'包含一列“companyID”,该列包

我正在使用一个设计拙劣的数据库,我不能自由地进行重组。在这个数据库中,有三个表,我们称它们为‘companiesA’、‘companiesB’和‘items’,它们涉及我需要优化的查询companiesA'和companiesB'描述公司的方式相同,因为列值相同,但它们代表两个不同的公司组,并且具有不同的列名。本质上,ID和公司名称列在“companiesA”中是“aID”和“aName”,在“companiesB”中是“idB”和“nameB”items'包含一列“companyID”,该列包含来自两个公司表之一的外键值

我需要优化的查询从两个表的并集中获取一个页面的公司ID和名称,按名称列排序,并添加一个列,说明行的公司是否有任何与之关联的项。如果用户在前端请求,此查询还可以按公司名称进行筛选。在它当前的状态下,我认为它在公司*项目时间内运行,速度非常慢:

select
  a.aID as companyID,
  a.aName as companyName,
  (select
     count(companyID)
   from
     items
   where
     companyID = a.aID
  ) as items
from
  companiesA as a
where
  a.aName like '%<string>%'

union

select
  b.idB as companyID,
  b.nameB as companyName,
  (select
     count(companyID)
   from
     items
   where
     companyID = b.idB
  ) as items
from
  companiesB as b
where
  b.nameB like '%<string>%'

order by
  companyName ASC
limit
  [optional_starting_index, ] 50;
items列是否包含实际计数并不重要,因为此查询返回的是一个完整的“items”表的值,这是我唯一能够清楚返回该值的方法。我想我可以算自己幸运,因为有1500家公司和9000个项目,这个算法只需要7秒钟


如果我是用另一种语言写的,我自己也可以用这种语言访问这些表,我可以很容易地用Ocompanies+items来写,但是我发现很难在MySQL中做到这一点。是否可以这样做,最好不使用存储函数或过程?如果需要的话,我可以添加它们,但是我很难通过phpMyAdmin添加它们,因为服务器的主机只允许该接口通过GUI访问数据库。

在这个解决方案中,我大胆地假设,通过使用Union All,每个表中的公司名称都是唯一的。如果不是这样,那么你可以切换回Union,但是你会得到让列表独一无二的性能打击。基本上,我消除了使用派生表返回计数的相关子查询的需要

Select Companies.CompanyID, Companies.CompanyName
    , Coalesce(ItemTotals.ItemCount,0) As ItemCount
From    (
        Select a.aID As CompanyID, a.aName As CompanyName
        From companiesA As a
        Where a.aName Like '%<string>%'
        Union All
        Select b.IDB, b.nameB
        From companiesB As b
        Where b.bName Like '%<string>%'
        ) As Companies
    Left Join   (
                Select companyID, Count(*) As ItemCount
                From items
                Group By companyID
                ) As ItemTotals
            On ItemTotals.companyID = Companies.CompanyID
Order By Company.CompanyName

在这个解决方案中,我大胆地假设,通过使用UNIONALL,每个表中的公司名称都是唯一的。如果不是这样,那么你可以切换回Union,但是你会得到让列表独一无二的性能打击。基本上,我消除了使用派生表返回计数的相关子查询的需要

Select Companies.CompanyID, Companies.CompanyName
    , Coalesce(ItemTotals.ItemCount,0) As ItemCount
From    (
        Select a.aID As CompanyID, a.aName As CompanyName
        From companiesA As a
        Where a.aName Like '%<string>%'
        Union All
        Select b.IDB, b.nameB
        From companiesB As b
        Where b.bName Like '%<string>%'
        ) As Companies
    Left Join   (
                Select companyID, Count(*) As ItemCount
                From items
                Group By companyID
                ) As ItemTotals
            On ItemTotals.companyID = Companies.CompanyID
Order By Company.CompanyName

我测试了这两个版本。第一个在0.2秒以下运行,这很好。第二个需要6.5秒,相当于我的版本,所以它无法运行。不过,谢谢你的回答;这教会了我很多。我测试了两个版本。第一个在0.2秒以下运行,这很好。第二个需要6.5秒,相当于我的版本,所以它无法运行。不过,谢谢你的回答;这教会了我很多。