[英]Mysql optimisation in one query
我有一些表具有約1000萬行。 該查詢的執行時間約為10分鍾:
SELECT
c.id,
CONCAT_WS(', ', country.name, region.name, c.name) AS [text]
FROM city_name AS cn
INNER JOIN city AS c
ON c.id = cn.city_id
INNER JOIN country
ON country.id = cn.country_id
INNER JOIN region
ON region.id = cn.region_id
WHERE cn.name LIKE '%:q%'
GROUP BY cn.city_id
LIMIT 50
但是,當我進行兩個查詢時,它的執行時間約為5秒鍾:
第一:
SELECT
city_id
FROM city_name
WHERE name LIKE '%:q%'
GROUP BY city_id
LIMIT 50
第二個:
SELECT
c.id,
CONCAT_WS(', ',country.name,region.name,c.name) AS text
FROM city AS c
INNER JOIN country
ON country.id = c.country_id
INNER JOIN region
ON region.id = region_id
WHERE c.id IN (:ids)
如何將其優化為一個查詢?
謝謝。
您是否嘗試過像這樣的內部查詢。
SELECT
c.id, CONCAT_WS(', ',country.name,region.name,c.name) AS text
FROM
city AS c
INNER JOIN
country ON country.id = c.country_id
INNER JOIN
region ON region.id = region_id
WHERE
c.id IN (
SELECT
city_id
FROM
city_name
WHERE
name LIKE '%:q%'
GROUP BY
city_id
LIMIT 50
)
或者嘗試將過濾器cn.name LIKE '%:q%'
從cn.name LIKE '%:q%'
第一個JOIN的ON子句
我更精通T-SQL,所以請稍稍改動一些語法,請原諒我。 希望這個概念很清楚。
SELECT
c.id, CONCAT_WS(', ',country.name,region.name,c.name) AS text
FROM
(SELECT city_id
FROM city_name
WHERE name LIKE '%:q%'
GROUP BY city_id) AS c
INNER JOIN
country ON country.id = c.country_id
INNER JOIN
region ON region.id = region_id
WHERE
c.id IN (:ids)
連接每個表,然后在最后進行昂貴的過濾,這意味着它需要處理大量結果。 如果僅在city_name表上首先進行昂貴的過濾,然后再進行聯接,則可大大減少聯接所涉及的行數。
YMMV,但這種策略雖然不盡人意,但過去對我來說效果很好。 在T-SQL中,我通常也將第一個結果放入臨時表或CTE中,但是我不確定在MySql中如何工作,因此請考慮對這些領域進行一些其他研究以提高性能。
“規范化,但不要過度規范化”。
通常對城市+國家/地區進行標准化是過度標准化的一個例子。 建議使用一個包含這三列的表,而不是一個三表JOIN
。 還建議使用標准的2個字母的country_code CHAR(2) CHARACTER SET ascii
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.