簡體   English   中英

一次查詢中的MySQL優化

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM