SQL Select Top with Left Join 和 Where 子句

Posted

技术标签:

【中文标题】SQL Select Top with Left Join 和 Where 子句【英文标题】:SQL Select Top with Left Join and Where clause 【发布时间】:2019-02-03 13:27:22 【问题描述】:

我有两个数据库表:

城市与列:

Country_Code | City_Code | City_Name  

国家/地区与列

Country_Code | Country_Name

根据用户输入的几个字符,它检查City_Name 列以返回结果以填充City 自动完成框。结果需要有城市代码、城市名称、国家代码和国家名称,因此需要加入。

我使用的查询是

 SELECT TOP 10 
     ci.Country_Code, ci.City_Code, ci.City_Name, co.Country_Name  
 FROM 
     Cities ci 
 LEFT OUTER JOIN 
     Countries co ON ci.Country_Code = co.Country_Code  
 WHERE 
     ci.City_Name LIKE '@CityName'  
 ORDER BY 
     ci.City_Name  

我得到的结果是正确的,但是查询需要很长时间才能完成。据我了解,首先,结果包含两个表的连接,然后 where 子句仅用于获取特定行,这些行按城市名称排序并返回前 10 个结果。

我的问题是,有没有办法加快查询速度。是否检查了 where 子句,然后只执行连接,最好还是只对前 10 个结果执行它?我尝试将我的WHERE 子句放在ON 子句中,但这给出了错误的结果。


编辑:@CityName 包含用户输入的 2-3 个字符,然后是 '%'。

【问题讨论】:

性能故障排除高度特定于供应商 - 所以请添加一个标签来指定您是否使用mysqlpostgresqlsql-serveroracledb2 - 或完全不同的东西。 @CityName 长什么样子? 慢有多慢?世界上有数千个城市,而不是数百万个。桌子有多大? 【参考方案1】:

我建议首先在 Countries.Country_Code 上添加 聚集索引(如果还没有,也将其作为国家表的主键)。索引会对表进行排序,从而提高连接中的搜索速度。

【讨论】:

可能还需要在CityName上添加索引【参考方案2】:

这似乎是您的查询:

SELECT TOP 10 ci.Country_Code, ci.City_Code, ci.City_Name, co.Country_Name  
FROM Cities ci LEFT OUTER JOIN 
     Countries co
     ON ci.Country_Code = co.Country_Code  
WHERE ci.City_Name LIKE @CityName  
ORDER BY ci.City_Name  ;

@CityName 周围不需要引号。

我不明白LEFT JOIN。这表明有些城市没有有效的Country_Code——这似乎不太可能。

假设@CityName not 是否以通配符开头(如您的问题所建议的那样),那么这可以利用索引。我建议以下索引:

cities(city_name, country_code) countries(country_code, country_name)

如果country_code 是主键,则不需要第二个。

【讨论】:

以上是关于SQL Select Top with Left Join 和 Where 子句的主要内容,如果未能解决你的问题,请参考以下文章

将“SELECT TOP (1) WITH TIES”转换为 EF Core

SQL的执行顺序

安装和配置SQL Server 2016 With SP1

MySQL Left Join Subquery with *

Mysql left join with nested select慢,如何优化

jquery 中的 offset()