I have two database tables:
Cities with columns:
Country_Code | City_Code | City_Name
Countries with columns
Country_Code | Country_Name
Based on a few chars entered by User, it checks the City_Name
column to return results to populate a City
autocomplete box. The result needs to have the city code, city name, country code, and country name, hence the need for a join.
The query I am using is
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
The results I get are correct, but the query takes a long time to complete. From what I understand, first, the results contain join of both the tables, then the where clause kicks in to get the specific rows only, which are ordered by City Name and top 10 results returned.
My question is, is there a way to speed up the query. Have the where clause checked, and then only perform the join, better still perform it only on the top 10 results? I tried putting my WHERE
clause in the ON
clause, but that gave wrong results.
EDIT : @CityName contains 2-3 chars entered by the user and then a '%'.
I'd suggest start with adding clustered index on Countries.Country_Code
(also making it the primary key of the Countries table if it is not already so). An index would sort the table such that the search speed in join is increased.
This appears to be your query:
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 ;
Quotes should not be needed around @CityName
.
I don't understand the LEFT JOIN
. It suggests that there are cities without a valid Country_Code
-- and that seems unlikely.
Assuming @CityName
does not start with a wildcard (as suggested by your question), then this can make use of an index. I would suggest the following indexes:
cities(city_name, country_code)
countries(country_code, country_name)
The second is not needed if country_code
is a primary key.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.