簡體   English   中英

使用索引改進MySQL表

[英]Improving MySQL tables with Indexes

我對MySQL中的索引很新。 我知道,我應該早點調試它,但大多數項目都足夠小,我可以逃脫它;)

所以,現在我正在測試它。 我通過在查詢上運行EXPLAIN來完成測試:

查詢:

EXPLAIN SELECT a . *
FROM `tff__keywords2data` AS a
LEFT JOIN `tff__keywords` AS b ON a.keyword_id = b.id
WHERE (
b.keyword = 'dog' || b.keyword = 'black' || b.keyword = 'and' || b.keyword = 'white'
)
GROUP BY a.data_id
HAVING COUNT( a.data_id ) =4 

首先,沒有索引我得到了這些結果:

在此輸入圖像描述

然后,使用data_id和keyword_id上的索引,我得到了這個:

在此輸入圖像描述

據我所知,MySQL必須搜索的行數從61k減少到10k,這一定是好的嗎?

所以我的問題是,我在這里是否正確? 在嘗試優化時,我還有什么可以考慮的嗎?

更新:

此外,在AJ和Piskvor的一些幫助指出我的另一個表及其列關鍵字沒有索引后,我得到了這個:

在此輸入圖像描述

好大的改進! 對?

如您所見,用於表bkey仍為NULL 您可能希望在b.keyword上添加索引並b.keyword匹配

WHERE b.keyword IN ('dog','black','and','white')

這在功能上與WHERE子句不同,盡管它返回相同的結果。

看起來,您可能對全文搜索感興趣。

根據您想要實現的目標,您應該使用INNER JOIN替換LEFT JOIN INNER JOIN或將WHERE條件移動到ON子句中:

就像現在一樣:

SELECT  a.*
FROM    `tff__keywords2data` AS a
LEFT JOIN
        `tff__keywords` AS b
ON      b.id = a.keyword_id
WHERE   b.keyword = 'dog' || b.keyword = 'black' || b.keyword = 'and' || b.keyword = 'white'
GROUP BY
        a.data_id
HAVING  COUNT( a.data_id ) = 4 

您的查詢實際上是一個INNER連接(因為您在WHERE子句中有非空條件)。

此外,您應該使用本機ORIN結構,而不是使用位算術(不可思議):

SELECT  a.*
FROM    `tff__keywords2data` AS a
JOIN    `tff__keywords` AS b
ON      b.id = a.keyword_id
WHERE   b.keyword IN ('dog', 'black', 'and', 'white')
GROUP BY
        a.data_id
HAVING  COUNT(*) = 4 

您可能還想在ttf__keywords (keyword)上創建索引,該索引可以過濾您要搜索的keywords ,並從前導b選擇較少的記錄。

最后,如果您不需要對a.data_id隱式排序, a.data_id通過附加ORDER BY NULL來刪除它:

SELECT  a.*
FROM    `tff__keywords2data` AS a
JOIN    `tff__keywords` AS b
ON      b.id = a.keyword_id
WHERE   b.keyword IN ('dog', 'black', 'and', 'white')
GROUP BY
        a.data_id
HAVING  COUNT(*) = 4 
ORDER BY
        NULL

這將從您的計划中刪除filesort

是的,這有所改善(但從快速看,我認為可以更好地改進)。 你可以看到,查詢優化器現在看到AND USING keyword_id索引。 它已經將搜索的行從64283減少到10216.但是這仍然使用一個文件庫,希望其他人可以澄清類似於SQL Server表掃描? 這不好......我可能在那里錯了。

您現在應該能夠將表b中的行減少到10216以下

你正在對b.keyword進行字符串比較....在那里添加一個索引。

使用INNER JOIN而不是LEFT JOIN 左連接將返回連接表中不匹配的行,我認為您不需要這些行。

嘗試將索引放在WHERE子句中的所有內容中,以及JOIN中的任何內容,這樣就可以:

a.keyword_id b.id b.keyword

您可能還想嘗試向a.data_id添加索引,因為它位於“GROUP BY”中。 索引太多通常不是問題,除非您向大型表添加大量數據 - 這可能導致INSERT非常慢。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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