我想不出有效的SQL查询来解决这个问题

时间:2014-10-10 11:02:42

标签: mysql sql performance

我有以下SQL表:

公司:

╔═════╦══════════╦═════════╦═══════════╦══════════════════╦═════╗
║  #  ║   Name   ║ Country ║   City    ║     Address      ║ Nr. ║
╠═════╬══════════╬═════════╬═══════════╬══════════════════╬═════╣
║ 1   ║ T-Online ║ Germany ║ Frankfurt ║ Teststr.         ║  15 ║
║ 2   ║ Telecom  ║ Italy   ║ Rome      ║ Via test         ║  20 ║
║ 3   ║ Verizon  ║ USA     ║ New York  ║ Something street ║  53 ║
║ ... ║ ....     ║         ║           ║                  ║     ║
╚═════╩══════════╩═════════╩═══════════╩══════════════════╩═════╝

tagsForCompany:

╔═════════╦═════╗
║ Company ║ TID ║
╠═════════╬═════╣
║ 1       ║ 10  ║
║ 2       ║ 15  ║
║ 1       ║ 11  ║
║ 3       ║ 19  ║
║ 2       ║ 11  ║
╚═════════╩═════╝

标记:

╔════╦══════════════════════╗
║ ID ║ Name                 ║
╠════╬══════════════════════╣
║ 1  ║ Software Development ║
║ 2  ║ Hosting              ║
║ 3  ║ Restaurant           ║
║... ║ ....                 ║
╚════╩══════════════════════╝

(所有值都是示例,而不是真实表格中的内容!)

我需要搜索特定城市和国家/地区的公司并拥有特定标记。 例如,我搜索了美国纽约所有标签为Software Development的公司。 我只需要一个SQL查询即可。

我现在正在使用的是什么:

  • 我搜索指定城市和国家/地区的所有公司
  • 然后搜索给定标记的ID
  • 之后,我搜索所有具有该标签ID的公司
  • 最后,我过滤表公司输出所有符合这些规则的公司。

显然这种方法不适合在生产中使用,对性能的影响太大而无法使用。

编辑:感谢您的所有答案,我将尝试其中的每一个,最有效的一个将是批准的答案:)

5 个答案:

答案 0 :(得分:1)

您可以使用JOIN并在公司表中的国家/地区和城市添加索引

SELECT Name
FROM companies AS c INNER JOIN tagsForCompany AS tc ON c.id = tc.Company
INNER JOIN tags AS t ON t.id = tc.TID
WHERE city = "your_city" AND country = "your_country" AND t.Name REGEXP 'your_tag'

在此查询中,将首先使用INNER JOIN生成一个表,然后根据生成的新表进行过滤

但更好,更优化的解决方案可能是通过过滤城市和国家来使用子查询生成表格。还要在公司表中添加国家和城市的索引,因为这会减少很多时间。现在新的查询将是

SELECT c.Name
FROM 
  (SELECT id, Name
   FROM companies
   WHERE city = "your_city" AND country = "your_country" ) AS c
  INNER JOIN tagsForCompany AS tc ON c.id = tc.Company
  INNER JOIN tags AS t ON t.id = tc.TID
WHERE t.Name REGEXP 'your_tag'

添加索引ALTER TABLE tbl_name ADD INDEX index_name (column_list)的语法,它添加了一个普通索引,其中任何值可能会出现多次。

ALTER TABLE companies ADD INDEX city (city);
ALTER TABLE companies ADD INDEX country (country);

答案 1 :(得分:0)

试试这个

SELECT *
FROM companies c, tags t, tagsForCompany tfc
WHERE tfc.company = c.companyId
AND   t.ID = tfc.TID
AND   t.Name = 'Software Development'
AND   c.city = 'New York'
AND   c.Country = 'USA'

答案 2 :(得分:0)

确保在搜索之前将正确的行连接在一起。

select *
from companies c
inner join tagsForCompany tc on tc.Company = c.#
inner join tags t on t.ID = tc.TID
where c.Country = '<param>' and c.City = '<param>' and t.Name = 'Software Development'

答案 3 :(得分:0)

尝试以下:

select *
from companies
where companyid in (
    select Company
    from tagsForCompany TID = 1 and Company in (
        Select companyid
        from companies where city ='New York' and country ='USA'
    ) a
) b

答案 4 :(得分:0)

这个查询可以帮助你。

select * from companies c
left join tagsForCompany tc on c.company_id = tc.company_id
left join tags t on t.tag_id = tc.tag_id
where c.city = "your value" and c.country = "Your value" and tc.name = "your value"